Compare commits
8 Commits
v1.5.5
...
v1.4.1-rc2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72eff0bf5e | ||
|
|
39e97a6754 | ||
|
|
e4653b55c1 | ||
|
|
0b0cd67150 | ||
|
|
b4aa06aced | ||
|
|
d513c3beca | ||
|
|
06b54536cf | ||
|
|
b1d3274bce |
28
.drone.yml
28
.drone.yml
@@ -1,22 +1,8 @@
|
||||
---
|
||||
kind: pipeline
|
||||
name: default
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
pull: default
|
||||
image: rancher/dapper:1.10.3
|
||||
commands:
|
||||
- KERNEL_CHECK=0 dapper ci
|
||||
volumes:
|
||||
- name: socket
|
||||
path: /var/run/docker.sock
|
||||
|
||||
volumes:
|
||||
- name: socket
|
||||
host:
|
||||
path: /var/run/docker.sock
|
||||
pipeline:
|
||||
build:
|
||||
image: rancher/dapper:1.10.3
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
commands:
|
||||
- dapper ci
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,6 +17,5 @@
|
||||
__pycache__
|
||||
/.dapper
|
||||
/.trash-cache
|
||||
/trash.lock
|
||||
.idea
|
||||
.trash-conf
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FROM ubuntu:bionic
|
||||
# FROM arm64=arm64v8/ubuntu:bionic
|
||||
FROM ubuntu:16.04
|
||||
# FROM arm64=aarch64/ubuntu:16.04
|
||||
|
||||
# get the apt-cacher proxy set
|
||||
ARG APTPROXY=
|
||||
@@ -40,7 +40,7 @@ RUN echo "Acquire::http { Proxy \"$APTPROXY\"; };" >> /etc/apt/apt.conf.d/01prox
|
||||
|
||||
########## Dapper Configuration #####################
|
||||
|
||||
ENV DAPPER_ENV VERSION DEV_BUILD RUNTEST DEBUG APTPROXY ENGINE_REGISTRY_MIRROR KERNEL_CHECK APPEND_SYSTEM_IMAGES APPEND_USER_IMAGES
|
||||
ENV DAPPER_ENV VERSION DEV_BUILD RUNTEST DEBUG APTPROXY ENGINE_REGISTRY_MIRROR INTEGRATION_TESTS
|
||||
ENV DAPPER_DOCKER_SOCKET true
|
||||
ENV DAPPER_SOURCE /go/src/github.com/rancher/os
|
||||
ENV DAPPER_OUTPUT ./bin ./dist ./build/initrd ./build/kernel
|
||||
@@ -58,80 +58,77 @@ ARG OS_REPO=rancher
|
||||
ARG HOSTNAME_DEFAULT=rancher
|
||||
ARG DISTRIB_ID=RancherOS
|
||||
|
||||
ARG DOCKER_VERSION=1.11.2
|
||||
ARG DOCKER_PATCH_VERSION=v${DOCKER_VERSION}-ros1
|
||||
ARG DOCKER_BUILD_VERSION=1.10.3
|
||||
ARG DOCKER_BUILD_PATCH_VERSION=v${DOCKER_BUILD_VERSION}-ros1
|
||||
ARG SELINUX_POLICY_URL=https://github.com/rancher/refpolicy/releases/download/v0.0.3/policy.29
|
||||
|
||||
ARG KERNEL_VERSION=4.14.138-rancher
|
||||
ARG KERNEL_URL_amd64=https://github.com/rancher/os-kernel/releases/download/v${KERNEL_VERSION}/linux-${KERNEL_VERSION}-x86.tar.gz
|
||||
ARG KERNEL_URL_arm64=https://github.com/rancher/os-kernel/releases/download/v${KERNEL_VERSION}/linux-${KERNEL_VERSION}-arm64.tar.gz
|
||||
ARG KERNEL_VERSION_amd64=4.14.65-rancher
|
||||
ARG KERNEL_URL_amd64=https://github.com/rancher/os-kernel/releases/download/v${KERNEL_VERSION_amd64}/linux-${KERNEL_VERSION_amd64}-x86.tar.gz
|
||||
|
||||
ARG BUILD_DOCKER_URL_amd64=https://get.docker.com/builds/Linux/x86_64/docker-1.10.3
|
||||
ARG BUILD_DOCKER_URL_arm64=https://github.com/rancher/docker/releases/download/v1.10.3-ros1/docker-1.10.3_arm64
|
||||
ARG DOCKER_URL_amd64=https://get.docker.com/builds/Linux/x86_64/docker-${DOCKER_VERSION}.tgz
|
||||
ARG DOCKER_URL_arm64=https://github.com/rancher/docker/releases/download/${DOCKER_PATCH_VERSION}/docker-${DOCKER_VERSION}_arm64.tgz
|
||||
|
||||
ARG BUILD_DOCKER_URL_amd64=https://get.docker.com/builds/Linux/x86_64/docker-${DOCKER_BUILD_VERSION}
|
||||
ARG BUILD_DOCKER_URL_arm64=https://github.com/rancher/docker/releases/download/${DOCKER_BUILD_PATCH_VERSION}/docker-${DOCKER_BUILD_VERSION}_arm64
|
||||
|
||||
ARG OS_RELEASES_YML=https://releases.rancher.com/os
|
||||
|
||||
ARG OS_SERVICES_REPO=https://raw.githubusercontent.com/${OS_REPO}/os-services
|
||||
ARG IMAGE_NAME=${OS_REPO}/os
|
||||
ARG DFS_IMAGE=${OS_REPO}/docker:v${DOCKER_VERSION}-2
|
||||
|
||||
ARG OS_CONSOLE=default
|
||||
ARG OS_AUTOFORMAT=false
|
||||
ARG OS_BASE_URL_amd64=https://github.com/rancher/os-base/releases/download/v2018.02-3/os-base_amd64.tar.xz
|
||||
ARG OS_BASE_URL_arm64=https://github.com/rancher/os-base/releases/download/v2018.02-3/os-base_arm64.tar.xz
|
||||
|
||||
ARG OS_BASE_URL_amd64=https://github.com/rancher/os-base/releases/download/v2018.02.11-1/os-base_amd64.tar.xz
|
||||
ARG OS_BASE_URL_arm64=https://github.com/rancher/os-base/releases/download/v2018.02.11-1/os-base_arm64.tar.xz
|
||||
|
||||
ARG OS_INITRD_BASE_URL_amd64=https://github.com/rancher/os-initrd-base/releases/download/v2018.02.11-1/os-initrd-base-amd64.tar.gz
|
||||
ARG OS_INITRD_BASE_URL_arm64=https://github.com/rancher/os-initrd-base/releases/download/v2018.02.11-1/os-initrd-base-arm64.tar.gz
|
||||
|
||||
ARG SYSTEM_DOCKER_VERSION=17.06-ros6
|
||||
ARG SYSTEM_DOCKER_VERSION=17.06-ros4
|
||||
ARG SYSTEM_DOCKER_URL_amd64=https://github.com/rancher/os-system-docker/releases/download/${SYSTEM_DOCKER_VERSION}/docker-amd64-${SYSTEM_DOCKER_VERSION}.tgz
|
||||
ARG SYSTEM_DOCKER_URL_arm64=https://github.com/rancher/os-system-docker/releases/download/${SYSTEM_DOCKER_VERSION}/docker-arm64-${SYSTEM_DOCKER_VERSION}.tgz
|
||||
|
||||
ARG USER_DOCKER_VERSION=19.03.5
|
||||
ARG USER_DOCKER_ENGINE_VERSION=docker-${USER_DOCKER_VERSION}
|
||||
|
||||
ARG AZURE_SERVICE=false
|
||||
ARG PROXMOXVE_SERVICE=false
|
||||
ARG VMWARE_AUTOFORMAT=1
|
||||
ARG OPEN_VMTOOLS_VERSION=10.2.5-3
|
||||
######################################################
|
||||
|
||||
# Set up environment and export all ARGS as ENV
|
||||
ENV ARCH=${ARCH} \
|
||||
HOST_ARCH=${HOST_ARCH} \
|
||||
XZ_DEFAULTS="-T0"
|
||||
HOST_ARCH=${HOST_ARCH}
|
||||
|
||||
ENV BUILD_DOCKER_URL=BUILD_DOCKER_URL_${ARCH} \
|
||||
BUILD_DOCKER_URL_amd64=${BUILD_DOCKER_URL_amd64} \
|
||||
BUILD_DOCKER_URL_arm64=${BUILD_DOCKER_URL_arm64} \
|
||||
DAPPER_HOST_ARCH=${DAPPER_HOST_ARCH} \
|
||||
DFS_IMAGE=${DFS_IMAGE} \
|
||||
DISTRIB_ID=${DISTRIB_ID} \
|
||||
DOCKER_PATCH_VERSION=${DOCKER_PATCH_VERSION} \
|
||||
DOCKER_URL=DOCKER_URL_${ARCH} \
|
||||
DOCKER_URL_amd64=${DOCKER_URL_amd64} \
|
||||
DOCKER_URL_arm64=${DOCKER_URL_arm64} \
|
||||
DOCKER_VERSION=${DOCKER_VERSION} \
|
||||
DOWNLOADS=/usr/src/downloads \
|
||||
GOPATH=/go \
|
||||
GO_VERSION=1.8.5 \
|
||||
GOARCH=$ARCH \
|
||||
HOSTNAME_DEFAULT=${HOSTNAME_DEFAULT} \
|
||||
IMAGE_NAME=${IMAGE_NAME} \
|
||||
KERNEL_VERSION=${KERNEL_VERSION} \
|
||||
KERNEL_VERSION=${KERNEL_VERSION_amd64} \
|
||||
KERNEL_URL=KERNEL_URL_${ARCH} \
|
||||
KERNEL_URL_amd64=${KERNEL_URL_amd64} \
|
||||
KERNEL_URL_arm64=${KERNEL_URL_arm64} \
|
||||
OS_BASE_SHA1=OS_BASE_SHA1_${ARCH} \
|
||||
OS_BASE_URL=OS_BASE_URL_${ARCH} \
|
||||
OS_BASE_URL_amd64=${OS_BASE_URL_amd64} \
|
||||
OS_BASE_URL_arm64=${OS_BASE_URL_arm64} \
|
||||
OS_INITRD_BASE_URL=OS_INITRD_BASE_URL_${ARCH} \
|
||||
OS_INITRD_BASE_URL_amd64=${OS_INITRD_BASE_URL_amd64} \
|
||||
OS_INITRD_BASE_URL_arm64=${OS_INITRD_BASE_URL_arm64} \
|
||||
OS_RELEASES_YML=${OS_RELEASES_YML} \
|
||||
OS_REPO=${OS_REPO} \
|
||||
OS_SERVICES_REPO=${OS_SERVICES_REPO} \
|
||||
OS_CONSOLE=${OS_CONSOLE} \
|
||||
OS_AUTOFORMAT=${OS_AUTOFORMAT} \
|
||||
REPO_VERSION=master \
|
||||
SELINUX_POLICY_URL=${SELINUX_POLICY_URL} \
|
||||
SYSTEM_DOCKER_URL=SYSTEM_DOCKER_URL_${ARCH} \
|
||||
SYSTEM_DOCKER_URL_amd64=${SYSTEM_DOCKER_URL_amd64} \
|
||||
SYSTEM_DOCKER_URL_arm64=${SYSTEM_DOCKER_URL_arm64} \
|
||||
USER_DOCKER_VERSION=${USER_DOCKER_VERSION} \
|
||||
USER_DOCKER_ENGINE_VERSION=${USER_DOCKER_ENGINE_VERSION} \
|
||||
AZURE_SERVICE=${AZURE_SERVICE} \
|
||||
PROXMOXVE_SERVICE=${PROXMOXVE_SERVICE}
|
||||
VMWARE_AUTOFORMAT=${VMWARE_AUTOFORMAT} \
|
||||
OPEN_VMTOOLS_VERSION=${OPEN_VMTOOLS_VERSION}
|
||||
ENV PATH=${GOPATH}/bin:/usr/local/go/bin:$PATH
|
||||
|
||||
RUN mkdir -p ${DOWNLOADS}
|
||||
@@ -148,10 +145,7 @@ RUN curl -pfL ${SELINUX_POLICY_URL} > ${DOWNLOADS}/$(basename ${SELINUX_POLICY_U
|
||||
|
||||
# Install Go
|
||||
RUN wget -O - https://storage.googleapis.com/golang/go${GO_VERSION}.linux-${GOARCH}.tar.gz | tar -xzf - -C /usr/local && \
|
||||
go get github.com/rancher/trash
|
||||
|
||||
RUN mkdir -p ${GOPATH}/src/golang.org/x && cd ${GOPATH}/src/golang.org/x/ && git clone https://github.com/golang/tools && \
|
||||
cd tools && git checkout 6adeb8aab2ded9eb693b831d5fd090c10a6ebdfa -b temp && go get golang.org/x/lint/golint
|
||||
go get github.com/rancher/trash && go get github.com/golang/lint/golint
|
||||
|
||||
# Install Host Docker
|
||||
RUN curl -fL ${!BUILD_DOCKER_URL} > /usr/bin/docker && \
|
||||
|
||||
58
Makefile
58
Makefile
@@ -1,4 +1,4 @@
|
||||
TARGETS := $(shell ls scripts | grep -vE 'clean|run|help|release*|build-moby|run-moby')
|
||||
TARGETS := $(shell ls scripts | grep -vE 'clean|run|help|release|build-moby|run-moby')
|
||||
|
||||
.dapper:
|
||||
@echo Downloading dapper
|
||||
@@ -37,46 +37,36 @@ shell-bind: .dapper
|
||||
clean:
|
||||
@./scripts/clean
|
||||
|
||||
release: .dapper release-build
|
||||
release: .dapper release-build qcows
|
||||
|
||||
release-build:
|
||||
mkdir -p dist
|
||||
./.dapper release
|
||||
./.dapper release 2>&1 | tee dist/release.log
|
||||
|
||||
rpi64: .dapper
|
||||
./scripts/release-rpi64
|
||||
itest:
|
||||
mkdir -p dist
|
||||
./.dapper integration-test 2>&1 | tee dist/itest.log
|
||||
grep --binary-files=text FAIL dist/itest.log || true
|
||||
|
||||
qcows:
|
||||
cp dist/artifacts/rancheros.iso scripts/images/openstack/
|
||||
cd scripts/images/openstack && \
|
||||
APPEND="console=tty1 console=ttyS0,115200n8 printk.devkmsg=on rancher.autologin=ttyS0 panic=10" \
|
||||
NAME=openstack ../../../.dapper
|
||||
cd scripts/images/openstack && \
|
||||
APPEND="console=tty1 printk.devkmsg=on notsc clocksource=kvm-clock rancher.network.interfaces.eth0.ipv4ll rancher.cloud_init.datasources=[digitalocean] rancher.autologin=tty1 rancher.autologin=ttyS0 panic=10 rancher.resize_device=/dev/vda" \
|
||||
NAME=digitalocean ../../../.dapper
|
||||
cp ./scripts/images/openstack/dist/*.img dist/artifacts/
|
||||
|
||||
rpi64:
|
||||
# scripts/images/raspberry-pi-hypriot64/dist/rancheros-raspberry-pi.zip
|
||||
cp dist/artifacts/rootfs_arm64.tar.gz scripts/images/raspberry-pi-hypriot64/
|
||||
cd scripts/images/raspberry-pi-hypriot64/ \
|
||||
&& ../../../.dapper
|
||||
|
||||
vmware: .dapper
|
||||
mkdir -p dist
|
||||
APPEND_SYSTEM_IMAGES="rancher/os-openvmtools:10.3.10-2" \
|
||||
./.dapper release-vmware
|
||||
|
||||
hyperv: .dapper
|
||||
mkdir -p dist
|
||||
APPEND_SYSTEM_IMAGES="rancher/os-hypervvmtools:v4.14.138-rancher-1" \
|
||||
./.dapper release-hyperv
|
||||
|
||||
azurebase: .dapper
|
||||
mkdir -p dist
|
||||
AZURE_SERVICE="true" \
|
||||
APPEND_SYSTEM_IMAGES="rancher/os-hypervvmtools:v4.14.138-rancher-1 rancher/os-waagent:v2.2.34-1" \
|
||||
./.dapper release-azurebase
|
||||
|
||||
4glte: .dapper
|
||||
mkdir -p dist
|
||||
APPEND_SYSTEM_IMAGES="rancher/os-modemmanager:v1.6.4-1" \
|
||||
./.dapper release-4glte
|
||||
|
||||
proxmoxve: .dapper
|
||||
mkdir -p dist
|
||||
PROXMOXVE_SERVICE="true" \
|
||||
APPEND_SYSTEM_IMAGES="rancher/os-qemuguestagent:v2.8.1-2" \
|
||||
./.dapper release-proxmoxve
|
||||
|
||||
pingan: .dapper
|
||||
mkdir -p dist
|
||||
APPEND_SYSTEM_IMAGES="cnrancher/os-pingan-amc:v0.0.6-1" \
|
||||
./.dapper release-pingan
|
||||
INTEGRATION_TESTS=0 ./.dapper vmware-release 2>&1 | tee dist/release.log
|
||||
|
||||
help:
|
||||
@./scripts/help
|
||||
|
||||
135
README.md
135
README.md
@@ -1,9 +1,5 @@
|
||||
# RancherOS
|
||||
|
||||
[](https://drone-pr.rancher.io/rancher/os)
|
||||
[](https://store.docker.com/community/images/rancher/os)
|
||||
[](https://goreportcard.com/badge/github.com/rancher/os)
|
||||
|
||||
The smallest, easiest way to run Docker in production at scale. Everything in RancherOS is a container managed by Docker. This includes system services such as udev and rsyslog. RancherOS includes only the bare minimum amount of software needed to run Docker. This keeps the binary download of RancherOS very small. Everything else can be pulled in dynamically through Docker.
|
||||
|
||||
## How this works
|
||||
@@ -18,68 +14,52 @@ it would really be bad if somebody did `docker rm -f $(docker ps -qa)` and delet
|
||||
|
||||
## Release
|
||||
|
||||
- **v1.5.4 - Docker 18.09.08 - Linux 4.14.138**
|
||||
- **Latest: v1.4.0 - Docker 18.03.1-ce - Linux 4.14.32**
|
||||
- **Stable: v1.4.0 - Docker 18.03.1-ce - Linux 4.14.32**
|
||||
|
||||
### ISO
|
||||
|
||||
- https://releases.rancher.com/os/v1.5.4/rancheros.iso
|
||||
- https://releases.rancher.com/os/v1.5.4/hyperv/rancheros.iso
|
||||
- https://releases.rancher.com/os/v1.5.4/4glte/rancheros.iso
|
||||
- https://releases.rancher.com/os/v1.5.4/vmware/rancheros.iso
|
||||
|
||||
#### Special docker-machine Links
|
||||
|
||||
- https://releases.rancher.com/os/v1.5.4/vmware/rancheros-autoformat.iso
|
||||
- https://releases.rancher.com/os/v1.5.4/proxmoxve/rancheros-autoformat.iso
|
||||
- https://releases.rancher.com/os/latest/rancheros.iso
|
||||
- https://releases.rancher.com/os/v1.4.0/rancheros.iso
|
||||
|
||||
### Additional Downloads
|
||||
|
||||
#### AMD64 Links
|
||||
#### Latest Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.4/initrd
|
||||
* https://releases.rancher.com/os/v1.5.4/vmlinuz
|
||||
* https://releases.rancher.com/os/v1.5.4/rancheros.ipxe
|
||||
* https://releases.rancher.com/os/v1.5.4/rootfs.tar.gz
|
||||
* https://releases.rancher.com/os/latest/initrd
|
||||
* https://releases.rancher.com/os/latest/iso-checksums.txt
|
||||
* https://releases.rancher.com/os/latest/rancheros-openstack.img
|
||||
* https://releases.rancher.com/os/latest/rancheros-digitalocean.img
|
||||
* https://releases.rancher.com/os/latest/rancheros-cloudstack.img
|
||||
* https://releases.rancher.com/os/latest/rancheros-aliyun.vhd
|
||||
* https://releases.rancher.com/os/latest/rancheros.ipxe
|
||||
* https://releases.rancher.com/os/latest/rancheros-gce.tar.gz
|
||||
* https://releases.rancher.com/os/latest/rootfs.tar.gz
|
||||
* https://releases.rancher.com/os/latest/vmlinuz
|
||||
* https://releases.rancher.com/os/latest/rancheros-vmware.iso
|
||||
|
||||
#### ARM64 Links
|
||||
#### v1.4.0 Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.4/arm64/initrd
|
||||
* https://releases.rancher.com/os/v1.5.4/arm64/vmlinuz
|
||||
* https://releases.rancher.com/os/v1.5.4/arm64/rootfs_arm64.tar.gz
|
||||
* https://releases.rancher.com/os/v1.5.4/arm64/rancheros-raspberry-pi64.zip
|
||||
* https://releases.rancher.com/os/v1.4.0/initrd
|
||||
* https://releases.rancher.com/os/v1.4.0/iso-checksums.txt
|
||||
* https://releases.rancher.com/os/v1.4.0/rancheros-openstack.img
|
||||
* https://releases.rancher.com/os/v1.4.0/rancheros-digitalocean.img
|
||||
* https://releases.rancher.com/os/v1.4.0/rancheros-cloudstack.img
|
||||
* https://releases.rancher.com/os/v1.4.0/rancheros-aliyun.vhd
|
||||
* https://releases.rancher.com/os/v1.4.0/rancheros.ipxe
|
||||
* https://releases.rancher.com/os/v1.4.0/rancheros-gce.tar.gz
|
||||
* https://releases.rancher.com/os/v1.4.0/rootfs.tar.gz
|
||||
* https://releases.rancher.com/os/v1.4.0/vmlinuz
|
||||
* https://releases.rancher.com/os/v1.4.0/rancheros-vmware.iso
|
||||
|
||||
#### Cloud Links
|
||||
#### ARM Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.4/rancheros-openstack.img
|
||||
* https://releases.rancher.com/os/v1.5.4/rancheros-digitalocean.img
|
||||
* https://releases.rancher.com/os/v1.5.4/rancheros-cloudstack.img
|
||||
* https://releases.rancher.com/os/v1.5.4/rancheros-aliyun.vhd
|
||||
* https://releases.rancher.com/os/v1.5.4/rancheros-gce.tar.gz
|
||||
* https://releases.rancher.com/os/latest/rootfs_arm64.tar.gz
|
||||
* https://releases.rancher.com/os/latest/rancheros-raspberry-pi64.zip
|
||||
* https://releases.rancher.com/os/v1.4.0/rootfs_arm64.tar.gz
|
||||
* https://releases.rancher.com/os/v1.4.0/rancheros-raspberry-pi64.zip
|
||||
|
||||
#### VMware Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.4/vmware/initrd
|
||||
* https://releases.rancher.com/os/v1.5.4/vmware/rancheros.vmdk
|
||||
* https://releases.rancher.com/os/v1.5.4/vmware/rootfs.tar.gz
|
||||
|
||||
#### Hyper-V Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.4/hyperv/initrd
|
||||
* https://releases.rancher.com/os/v1.5.4/hyperv/rootfs.tar.gz
|
||||
|
||||
#### Proxmox VE Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.4/proxmoxve/initrd
|
||||
* https://releases.rancher.com/os/v1.5.4/proxmoxve/rootfs.tar.gz
|
||||
|
||||
#### 4G-LTE Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.4/4glte/initrd
|
||||
* https://releases.rancher.com/os/v1.5.4/4glte/rootfs.tar.gz
|
||||
|
||||
**Note**:
|
||||
1. you can use `http` instead of `https` in the above URLs, e.g. for iPXE.
|
||||
2. you can use `latest` instead of `v1.5.4` in the above URLs if you want to get the latest version.
|
||||
**Note**: you can use `http` instead of `https` in the above URLs, e.g. for iPXE.
|
||||
|
||||
### Amazon
|
||||
|
||||
@@ -89,30 +69,35 @@ SSH keys are added to the **`rancher`** user, so you must log in using the **ran
|
||||
|
||||
Region | Type | AMI
|
||||
-------|------|------
|
||||
eu-north-1 | HVM | [ami-008be767228de6683](https://eu-north-1.console.aws.amazon.com/ec2/home?region=eu-north-1#launchInstanceWizard:ami=ami-008be767228de6683)
|
||||
ap-south-1 | HVM | [ami-06d0903ccdd125c0c](https://ap-south-1.console.aws.amazon.com/ec2/home?region=ap-south-1#launchInstanceWizard:ami=ami-06d0903ccdd125c0c)
|
||||
eu-west-3 | HVM | [ami-0cbb2f6862669fe62](https://eu-west-3.console.aws.amazon.com/ec2/home?region=eu-west-3#launchInstanceWizard:ami=ami-0cbb2f6862669fe62)
|
||||
eu-west-2 | HVM | [ami-0d5ce579aeef247e6](https://eu-west-2.console.aws.amazon.com/ec2/home?region=eu-west-2#launchInstanceWizard:ami=ami-0d5ce579aeef247e6)
|
||||
eu-west-1 | HVM | [ami-0f48831932827ad91](https://eu-west-1.console.aws.amazon.com/ec2/home?region=eu-west-1#launchInstanceWizard:ami=ami-0f48831932827ad91)
|
||||
ap-northeast-2 | HVM | [ami-0fcc552e7ee5cb04c](https://ap-northeast-2.console.aws.amazon.com/ec2/home?region=ap-northeast-2#launchInstanceWizard:ami=ami-0fcc552e7ee5cb04c)
|
||||
ap-northeast-1 | HVM | [ami-082e73823959a006f](https://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#launchInstanceWizard:ami=ami-082e73823959a006f)
|
||||
sa-east-1 | HVM | [ami-0613568e5abe888e8](https://sa-east-1.console.aws.amazon.com/ec2/home?region=sa-east-1#launchInstanceWizard:ami=ami-0613568e5abe888e8)
|
||||
ca-central-1 | HVM | [ami-0fe07f3c02d7e1b73](https://ca-central-1.console.aws.amazon.com/ec2/home?region=ca-central-1#launchInstanceWizard:ami=ami-0fe07f3c02d7e1b73)
|
||||
ap-southeast-1 | HVM | [ami-0dc36da6fc839e3b4](https://ap-southeast-1.console.aws.amazon.com/ec2/home?region=ap-southeast-1#launchInstanceWizard:ami=ami-0dc36da6fc839e3b4)
|
||||
ap-southeast-2 | HVM | [ami-0d1e30aed40a09e7a](https://ap-southeast-2.console.aws.amazon.com/ec2/home?region=ap-southeast-2#launchInstanceWizard:ami=ami-0d1e30aed40a09e7a)
|
||||
eu-central-1 | HVM | [ami-0079d316193c1c1f2](https://eu-central-1.console.aws.amazon.com/ec2/home?region=eu-central-1#launchInstanceWizard:ami=ami-0079d316193c1c1f2)
|
||||
us-east-1 | HVM | [ami-03383c16defb1ed02](https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#launchInstanceWizard:ami=ami-03383c16defb1ed02)
|
||||
us-east-2 | HVM | [ami-0ebe6ed6e656d9aa9](https://us-east-2.console.aws.amazon.com/ec2/home?region=us-east-2#launchInstanceWizard:ami=ami-0ebe6ed6e656d9aa9)
|
||||
us-west-1 | HVM | [ami-09b8160a9edaeb22a](https://us-west-1.console.aws.amazon.com/ec2/home?region=us-west-1#launchInstanceWizard:ami=ami-09b8160a9edaeb22a)
|
||||
us-west-2 | HVM | [ami-0d554a1dd1d4ed527](https://us-west-2.console.aws.amazon.com/ec2/home?region=us-west-2#launchInstanceWizard:ami=ami-0d554a1dd1d4ed527)
|
||||
cn-north-1 | HVM | [ami-025d9b43810675e5f](https://cn-north-1.console.amazonaws.cn/ec2/home?region=cn-north-1#launchInstanceWizard:ami=ami-025d9b43810675e5f)
|
||||
cn-northwest-1 | HVM | [ami-00be191a22f30767e](https://cn-northwest-1.console.amazonaws.cn/ec2/home?region=cn-northwest-1#launchInstanceWizard:ami=ami-00be191a22f30767e)
|
||||
ap-south-1 | HVM | [ami-f4426c9b](https://ap-south-1.console.aws.amazon.com/ec2/home?region=ap-south-1#launchInstanceWizard:ami=ami-f4426c9b)
|
||||
eu-west-3 | HVM | [ami-6444f519](https://eu-west-3.console.aws.amazon.com/ec2/home?region=eu-west-3#launchInstanceWizard:ami=ami-6444f519)
|
||||
eu-west-2 | HVM | [ami-1e7f9379](https://eu-west-2.console.aws.amazon.com/ec2/home?region=eu-west-2#launchInstanceWizard:ami=ami-1e7f9379)
|
||||
eu-west-1 | HVM | [ami-447a7f3d](https://eu-west-1.console.aws.amazon.com/ec2/home?region=eu-west-1#launchInstanceWizard:ami=ami-447a7f3d)
|
||||
ap-northeast-2 | HVM | [ami-5492393a](https://ap-northeast-2.console.aws.amazon.com/ec2/home?region=ap-northeast-2#launchInstanceWizard:ami=ami-5492393a)
|
||||
ap-northeast-1 | HVM | [ami-96e218e9](https://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#launchInstanceWizard:ami=ami-96e218e9)
|
||||
sa-east-1 | HVM | [ami-1a217876](https://sa-east-1.console.aws.amazon.com/ec2/home?region=sa-east-1#launchInstanceWizard:ami=ami-1a217876)
|
||||
ca-central-1 | HVM | [ami-eef6758a](https://ca-central-1.console.aws.amazon.com/ec2/home?region=ca-central-1#launchInstanceWizard:ami=ami-eef6758a)
|
||||
ap-southeast-1 | HVM | [ami-0716287b](https://ap-southeast-1.console.aws.amazon.com/ec2/home?region=ap-southeast-1#launchInstanceWizard:ami=ami-0716287b)
|
||||
ap-southeast-2 | HVM | [ami-4ae73528](https://ap-southeast-2.console.aws.amazon.com/ec2/home?region=ap-southeast-2#launchInstanceWizard:ami=ami-4ae73528)
|
||||
eu-central-1 | HVM | [ami-1686b3fd](https://eu-central-1.console.aws.amazon.com/ec2/home?region=eu-central-1#launchInstanceWizard:ami=ami-1686b3fd)
|
||||
us-east-1 | HVM | [ami-99c5ade6](https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#launchInstanceWizard:ami=ami-99c5ade6)
|
||||
us-east-2 | HVM | [ami-504b7435](https://us-east-2.console.aws.amazon.com/ec2/home?region=us-east-2#launchInstanceWizard:ami=ami-504b7435)
|
||||
us-west-1 | HVM | [ami-1e63797e](https://us-west-1.console.aws.amazon.com/ec2/home?region=us-west-1#launchInstanceWizard:ami=ami-1e63797e)
|
||||
us-west-2 | HVM | [ami-e59ae09d](https://us-west-2.console.aws.amazon.com/ec2/home?region=us-west-2#launchInstanceWizard:ami=ami-e59ae09d)
|
||||
cn-north-1 | HVM | [ami-0a5d8367](https://cn-north-1.console.amazonaws.cn/ec2/home?region=cn-north-1#launchInstanceWizard:ami=ami-0a5d8367)
|
||||
cn-northwest-1 | HVM | [ami-40a1b522](https://cn-northwest-1.console.amazonaws.cn/ec2/home?region=cn-northwest-1#launchInstanceWizard:ami=ami-40a1b522)
|
||||
|
||||
Additionally, images are available with support for Amazon EC2 Container Service (ECS) [here](https://rancher.com/docs/os/v1.x/en/installation/amazon-ecs/#amazon-ecs-enabled-amis).
|
||||
|
||||
### Azure
|
||||
### Google Compute Engine
|
||||
|
||||
You can get RancherOS in the [Azure Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/rancher.rancheros), currently only the `rancher` user can be logged in through SSH keys.
|
||||
We are providing a disk image that users can download and import for use in Google Compute Engine. The image can be obtained from the release artifacts for RancherOS.
|
||||
|
||||
[Download Latest Image](https://releases.rancher.com/os/latest/rancheros-gce.tar.gz)
|
||||
|
||||
[Download Stable Image](https://releases.rancher.com/os/v1.4.0/rancheros-gce.tar.gz)
|
||||
|
||||
Please follow the directions at our [docs to launch in GCE](https://rancher.com/docs/os/v1.x/en/installation/running-rancheros/cloud/gce/).
|
||||
|
||||
## Documentation for RancherOS
|
||||
|
||||
@@ -130,7 +115,7 @@ Please submit any **Rancher** bugs, issues, and feature requests to [rancher/ran
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2014-2019 [Rancher Labs, Inc.](http://rancher.com)
|
||||
Copyright (c) 2014-2018 [Rancher Labs, Inc.](http://rancher.com)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -12,10 +12,9 @@ import (
|
||||
rancherConfig "github.com/rancher/os/config"
|
||||
"github.com/rancher/os/config/cloudinit/config"
|
||||
"github.com/rancher/os/config/cloudinit/system"
|
||||
"github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
@@ -181,17 +180,7 @@ func applyPreConsole(cfg *rancherConfig.CloudConfig) {
|
||||
}
|
||||
|
||||
func resizeDevice(cfg *rancherConfig.CloudConfig) error {
|
||||
partition := "1"
|
||||
targetPartition := fmt.Sprintf("%s%s", cfg.Rancher.ResizeDevice, partition)
|
||||
|
||||
if strings.Contains(cfg.Rancher.ResizeDevice, "mmcblk") {
|
||||
partition = "2"
|
||||
targetPartition = fmt.Sprintf("%sp%s", cfg.Rancher.ResizeDevice, partition)
|
||||
} else if strings.Contains(cfg.Rancher.ResizeDevice, "nvme") {
|
||||
targetPartition = fmt.Sprintf("%sp%s", cfg.Rancher.ResizeDevice, partition)
|
||||
}
|
||||
|
||||
cmd := exec.Command("growpart", cfg.Rancher.ResizeDevice, partition)
|
||||
cmd := exec.Command("growpart", cfg.Rancher.ResizeDevice, "1")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Run()
|
||||
@@ -204,6 +193,10 @@ func resizeDevice(cfg *rancherConfig.CloudConfig) error {
|
||||
return err
|
||||
}
|
||||
|
||||
targetPartition := fmt.Sprintf("%s1", cfg.Rancher.ResizeDevice)
|
||||
if strings.Contains(cfg.Rancher.ResizeDevice, "nvme") {
|
||||
targetPartition = fmt.Sprintf("%sp1", cfg.Rancher.ResizeDevice)
|
||||
}
|
||||
cmd = exec.Command("resize2fs", targetPartition)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
@@ -24,6 +24,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
|
||||
"github.com/rancher/os/cmd/control"
|
||||
"github.com/rancher/os/cmd/network"
|
||||
rancherConfig "github.com/rancher/os/config"
|
||||
@@ -32,24 +34,18 @@ import (
|
||||
"github.com/rancher/os/config/cloudinit/datasource/configdrive"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/file"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/aliyun"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/azure"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/cloudstack"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/digitalocean"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/ec2"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/exoscale"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/gce"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/packet"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/proccmdline"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/proxmox"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/tftp"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/url"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/vmware"
|
||||
"github.com/rancher/os/config/cloudinit/pkg"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/netconf"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -69,11 +65,6 @@ func Main() {
|
||||
if err := saveCloudConfig(); err != nil {
|
||||
log.Errorf("Failed to save cloud-config: %v", err)
|
||||
}
|
||||
|
||||
// exit wpa_supplicant
|
||||
netconf.StopWpaSupplicant()
|
||||
// exit dhcpcd
|
||||
netconf.StopDhcpcd()
|
||||
}
|
||||
|
||||
func saveCloudConfig() error {
|
||||
@@ -83,7 +74,7 @@ func saveCloudConfig() error {
|
||||
log.Debugf("init: SaveCloudConfig(pre ApplyNetworkConfig): %#v", cfg.Rancher.Network)
|
||||
network.ApplyNetworkConfig(cfg)
|
||||
|
||||
log.Infof("datasources that will be considered: %#v", cfg.Rancher.CloudInit.Datasources)
|
||||
log.Infof("datasources that will be consided: %#v", cfg.Rancher.CloudInit.Datasources)
|
||||
dss := getDatasources(cfg.Rancher.CloudInit.Datasources)
|
||||
if len(dss) == 0 {
|
||||
log.Errorf("currentDatasource - none found")
|
||||
@@ -101,6 +92,23 @@ func saveCloudConfig() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func RequiresNetwork(datasource string) bool {
|
||||
// TODO: move into the datasources (and metadatasources)
|
||||
// and then we can enable that platforms defaults..
|
||||
parts := strings.SplitN(datasource, ":", 2)
|
||||
requiresNetwork, ok := map[string]bool{
|
||||
"ec2": true,
|
||||
"file": false,
|
||||
"url": true,
|
||||
"cmdline": true,
|
||||
"configdrive": false,
|
||||
"digitalocean": true,
|
||||
"gce": true,
|
||||
"packet": true,
|
||||
}[parts[0]]
|
||||
return ok && requiresNetwork
|
||||
}
|
||||
|
||||
func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadata) error {
|
||||
os.MkdirAll(rancherConfig.CloudConfigDir, os.ModeDir|0600)
|
||||
|
||||
@@ -230,14 +238,7 @@ func getDatasources(datasources []string) []datasource.Datasource {
|
||||
|
||||
switch parts[0] {
|
||||
case "*":
|
||||
dss = append(dss, getDatasources([]string{"configdrive", "vmware", "ec2", "digitalocean", "packet", "gce", "cloudstack", "exoscale", "proxmox"})...)
|
||||
case "proxmox":
|
||||
if root == "" {
|
||||
root = "/media/pve-config"
|
||||
}
|
||||
dss = append(dss, proxmox.NewDataSource(root))
|
||||
case "exoscale":
|
||||
dss = append(dss, exoscale.NewDatasource(root))
|
||||
dss = append(dss, getDatasources([]string{"configdrive", "vmware", "ec2", "digitalocean", "packet", "gce", "cloudstack"})...)
|
||||
case "cloudstack":
|
||||
for _, source := range cloudstack.NewDatasource(root) {
|
||||
dss = append(dss, source)
|
||||
@@ -248,8 +249,6 @@ func getDatasources(datasources []string) []datasource.Datasource {
|
||||
if root != "" {
|
||||
dss = append(dss, file.NewDatasource(root))
|
||||
}
|
||||
case "tftp":
|
||||
dss = append(dss, tftp.NewDatasource(root))
|
||||
case "url":
|
||||
if root != "" {
|
||||
dss = append(dss, url.NewDatasource(root))
|
||||
@@ -278,8 +277,6 @@ func getDatasources(datasources []string) []datasource.Datasource {
|
||||
}
|
||||
case "aliyun":
|
||||
dss = append(dss, aliyun.NewDatasource(root))
|
||||
case "azure":
|
||||
dss = append(dss, azure.NewDatasource(root))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,18 +284,12 @@ func getDatasources(datasources []string) []datasource.Datasource {
|
||||
}
|
||||
|
||||
func enableDoLinkLocal() {
|
||||
cfg := rancherConfig.LoadConfig()
|
||||
dhcpTimeout := cfg.Rancher.Defaults.Network.DHCPTimeout
|
||||
if cfg.Rancher.Network.DHCPTimeout > 0 {
|
||||
dhcpTimeout = cfg.Rancher.Network.DHCPTimeout
|
||||
}
|
||||
_, err := netconf.ApplyNetworkConfigs(&netconf.NetworkConfig{
|
||||
Interfaces: map[string]netconf.InterfaceConfig{
|
||||
"eth0": {
|
||||
IPV4LL: true,
|
||||
},
|
||||
},
|
||||
DHCPTimeout: dhcpTimeout,
|
||||
}, false, false)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to apply link local on eth0: %v", err)
|
||||
|
||||
@@ -8,10 +8,9 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
func AutologinMain() {
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
func BootstrapMain() {
|
||||
@@ -25,13 +23,6 @@ func BootstrapMain() {
|
||||
log.Debugf("bootstrapAction: loadingConfig")
|
||||
cfg := config.LoadConfig()
|
||||
|
||||
log.Debugf("bootstrapAction: Rngd(%v)", cfg.Rancher.State.Rngd)
|
||||
if cfg.Rancher.State.Rngd {
|
||||
if err := runRngd(); err != nil {
|
||||
log.Errorf("Failed to run rngd: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("bootstrapAction: MdadmScan(%v)", cfg.Rancher.State.MdadmScan)
|
||||
if cfg.Rancher.State.MdadmScan {
|
||||
if err := mdadmScan(); err != nil {
|
||||
@@ -39,20 +30,6 @@ func BootstrapMain() {
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("bootstrapAction: cryptsetup(%v)", cfg.Rancher.State.Cryptsetup)
|
||||
if cfg.Rancher.State.Cryptsetup {
|
||||
if err := cryptsetup(); err != nil {
|
||||
log.Errorf("Failed to run cryptsetup: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("bootstrapAction: LvmScan(%v)", cfg.Rancher.State.LvmScan)
|
||||
if cfg.Rancher.State.LvmScan {
|
||||
if err := vgchange(); err != nil {
|
||||
log.Errorf("Failed to run vgchange: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
stateScript := cfg.Rancher.State.Script
|
||||
log.Debugf("bootstrapAction: stateScript(%v)", stateScript)
|
||||
if stateScript != "" {
|
||||
@@ -91,56 +68,6 @@ func mdadmScan() error {
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func vgchange() error {
|
||||
cmd := exec.Command("vgchange", "--activate", "ay")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func cryptsetup() error {
|
||||
devices, err := util.BlkidType("crypto_LUKS")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, cryptdevice := range devices {
|
||||
fdRead, err := os.Open("/dev/console")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fdRead.Close()
|
||||
|
||||
fdWrite, err := os.OpenFile("/dev/console", os.O_WRONLY|os.O_APPEND, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fdWrite.Close()
|
||||
|
||||
cmd := exec.Command("cryptsetup", "luksOpen", cryptdevice, fmt.Sprintf("luks-%s", filepath.Base(cryptdevice)))
|
||||
cmd.Stdout = fdWrite
|
||||
cmd.Stderr = fdWrite
|
||||
cmd.Stdin = fdRead
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Errorf("Failed to run cryptsetup for %s: %v", cryptdevice, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runRngd() error {
|
||||
// use /dev/urandom as random number input for rngd
|
||||
// this is a really bad idea
|
||||
// since I am simple filling the kernel entropy pool with entropy coming from the kernel itself!
|
||||
// but this does not need to consider the user's hw rngd drivers.
|
||||
cmd := exec.Command("rngd", "-r", "/dev/urandom", "-q")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func runStateScript(script string) error {
|
||||
f, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
|
||||
@@ -4,11 +4,10 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/cmd/control/service"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
func Main() {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -12,13 +10,12 @@ import (
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
"github.com/rancher/os/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
func configSubcommands() []cli.Command {
|
||||
@@ -156,22 +153,6 @@ func env2map(env []string) map[string]string {
|
||||
}
|
||||
|
||||
func editSyslinux(c *cli.Context) error {
|
||||
// check whether is Raspberry Pi or not
|
||||
bytes, err := ioutil.ReadFile("/proc/device-tree/model")
|
||||
if err == nil && strings.Contains(strings.ToLower(string(bytes)), "raspberry") {
|
||||
buf := bufio.NewWriter(os.Stdout)
|
||||
fmt.Fprintln(buf, "raspberry pi can not use this command")
|
||||
buf.Flush()
|
||||
return errors.New("raspberry pi can not use this command")
|
||||
}
|
||||
|
||||
if isExist := checkGlobalCfg(); !isExist {
|
||||
buf := bufio.NewWriter(os.Stdout)
|
||||
fmt.Fprintln(buf, "global.cfg can not be found")
|
||||
buf.Flush()
|
||||
return errors.New("global.cfg can not be found")
|
||||
}
|
||||
|
||||
cmd := exec.Command("system-docker", "run", "--rm", "-it",
|
||||
"-v", "/:/host",
|
||||
"-w", "/host",
|
||||
@@ -299,12 +280,5 @@ func inputBytes(c *cli.Context) ([]byte, error) {
|
||||
}
|
||||
defer input.Close()
|
||||
}
|
||||
content, err := ioutil.ReadAll(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if bytes.Contains(content, []byte{13, 10}) {
|
||||
return nil, errors.New("file format shouldn't contain CRLF characters")
|
||||
}
|
||||
return content, nil
|
||||
return ioutil.ReadAll(input)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@ package control
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"os"
|
||||
)
|
||||
|
||||
func TestGenTpl(t *testing.T) {
|
||||
|
||||
@@ -5,19 +5,19 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/cmd/control/service"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/compose"
|
||||
"github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/pkg/util/network"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/docker/docker/reference"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/project/options"
|
||||
"golang.org/x/net/context"
|
||||
"github.com/rancher/os/cmd/control/service"
|
||||
"github.com/rancher/os/compose"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
"github.com/rancher/os/util/network"
|
||||
)
|
||||
|
||||
func consoleSubcommands() []cli.Command {
|
||||
@@ -43,14 +43,8 @@ func consoleSubcommands() []cli.Command {
|
||||
Action: consoleEnable,
|
||||
},
|
||||
{
|
||||
Name: "list",
|
||||
Usage: "list available consoles",
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "update, u",
|
||||
Usage: "update console cache",
|
||||
},
|
||||
},
|
||||
Name: "list",
|
||||
Usage: "list available consoles",
|
||||
Action: consoleList,
|
||||
},
|
||||
}
|
||||
@@ -133,7 +127,7 @@ func consoleEnable(c *cli.Context) error {
|
||||
|
||||
func consoleList(c *cli.Context) error {
|
||||
cfg := config.LoadConfig()
|
||||
consoles := availableConsoles(cfg, c.Bool("update"))
|
||||
consoles := availableConsoles(cfg)
|
||||
CurrentConsole := CurrentConsole()
|
||||
|
||||
for _, console := range consoles {
|
||||
@@ -150,20 +144,13 @@ func consoleList(c *cli.Context) error {
|
||||
}
|
||||
|
||||
func validateConsole(console string, cfg *config.CloudConfig) {
|
||||
consoles := availableConsoles(cfg, false)
|
||||
consoles := availableConsoles(cfg)
|
||||
if !service.IsLocalOrURL(console) && !util.Contains(consoles, console) {
|
||||
log.Fatalf("%s is not a valid console", console)
|
||||
}
|
||||
}
|
||||
|
||||
func availableConsoles(cfg *config.CloudConfig, update bool) []string {
|
||||
if update {
|
||||
err := network.UpdateCaches(cfg.Rancher.Repositories.ToArray(), "consoles")
|
||||
if err != nil {
|
||||
log.Debugf("Failed to update console caches: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
func availableConsoles(cfg *config.CloudConfig) []string {
|
||||
consoles, err := network.GetConsoles(cfg.Rancher.Repositories.ToArray())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
||||
@@ -7,21 +7,18 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strconv"
|
||||
"regexp"
|
||||
"strings"
|
||||
"syscall"
|
||||
"text/template"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/cmd/cloudinitexecute"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/config/cmdline"
|
||||
"github.com/rancher/os/pkg/compose"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
"golang.org/x/sys/unix"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -30,15 +27,18 @@ const (
|
||||
gettyCmd = "/sbin/agetty"
|
||||
rancherHome = "/home/rancher"
|
||||
startScript = "/opt/rancher/bin/start.sh"
|
||||
runLockDir = "/run/lock"
|
||||
sshdFile = "/etc/ssh/sshd_config"
|
||||
sshdTplFile = "/etc/ssh/sshd_config.tpl"
|
||||
)
|
||||
|
||||
type symlink struct {
|
||||
oldname, newname string
|
||||
}
|
||||
|
||||
func ConsoleInitMain() {
|
||||
if err := consoleInitFunc(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func consoleInitAction(c *cli.Context) error {
|
||||
return consoleInitFunc()
|
||||
}
|
||||
@@ -66,32 +66,8 @@ func consoleInitFunc() error {
|
||||
createHomeDir(rancherHome, 1100, 1100)
|
||||
createHomeDir(dockerHome, 1101, 1101)
|
||||
|
||||
// who & w command need this file
|
||||
if _, err := os.Stat("/run/utmp"); os.IsNotExist(err) {
|
||||
f, err := os.OpenFile("/run/utmp", os.O_RDWR|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
defer f.Close()
|
||||
}
|
||||
|
||||
// some software need this dir, like open-iscsi
|
||||
if _, err := os.Stat(runLockDir); os.IsNotExist(err) {
|
||||
if err = os.Mkdir(runLockDir, 0755); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
ignorePassword := false
|
||||
for _, d := range cfg.Rancher.Disable {
|
||||
if d == "password" {
|
||||
ignorePassword = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
password := cmdline.GetCmdline("rancher.password")
|
||||
if !ignorePassword && password != "" {
|
||||
if password != "" {
|
||||
cmd := exec.Command("chpasswd")
|
||||
cmd.Stdin = strings.NewReader(fmt.Sprint("rancher:", password))
|
||||
if err := cmd.Run(); err != nil {
|
||||
@@ -116,48 +92,18 @@ func consoleInitFunc() error {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
p, err := compose.GetProject(cfg, false, true)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
// check the multi engine service & generate the multi engine script
|
||||
for _, key := range p.ServiceConfigs.Keys() {
|
||||
serviceConfig, ok := p.ServiceConfigs.Get(key)
|
||||
if !ok {
|
||||
log.Errorf("Failed to get service config from the project")
|
||||
continue
|
||||
}
|
||||
if _, ok := serviceConfig.Labels[config.UserDockerLabel]; ok {
|
||||
err = util.GenerateDindEngineScript(serviceConfig.Labels[config.UserDockerLabel])
|
||||
if err != nil {
|
||||
log.Errorf("Failed to generate engine script: %v", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
baseSymlink := symLinkEngineBinary()
|
||||
|
||||
if _, err := os.Stat(dockerCompletionFile); err == nil {
|
||||
baseSymlink = append(baseSymlink, symlink{
|
||||
dockerCompletionFile, dockerCompletionLinkFile,
|
||||
})
|
||||
}
|
||||
|
||||
if cfg.Rancher.Console == "default" {
|
||||
// add iptables symlinks for default console
|
||||
baseSymlink = append(baseSymlink, []symlink{
|
||||
{"/usr/sbin/iptables", "/usr/sbin/iptables-save"},
|
||||
{"/usr/sbin/iptables", "/usr/sbin/iptables-restore"},
|
||||
{"/usr/sbin/iptables", "/usr/sbin/ip6tables"},
|
||||
{"/usr/sbin/iptables", "/usr/sbin/ip6tables-save"},
|
||||
{"/usr/sbin/iptables", "/usr/sbin/ip6tables-restore"},
|
||||
{"/usr/sbin/iptables", "/usr/bin/iptables-xml"},
|
||||
}...)
|
||||
}
|
||||
|
||||
for _, link := range baseSymlink {
|
||||
for _, link := range []symlink{
|
||||
{"/var/lib/rancher/engine/docker", "/usr/bin/docker"},
|
||||
{"/var/lib/rancher/engine/docker-init", "/usr/bin/docker-init"},
|
||||
{"/var/lib/rancher/engine/docker-containerd", "/usr/bin/docker-containerd"},
|
||||
{"/var/lib/rancher/engine/docker-containerd-ctr", "/usr/bin/docker-containerd-ctr"},
|
||||
{"/var/lib/rancher/engine/docker-containerd-shim", "/usr/bin/docker-containerd-shim"},
|
||||
{"/var/lib/rancher/engine/dockerd", "/usr/bin/dockerd"},
|
||||
{"/var/lib/rancher/engine/docker-proxy", "/usr/bin/docker-proxy"},
|
||||
{"/var/lib/rancher/engine/docker-runc", "/usr/bin/docker-runc"},
|
||||
{"/usr/share/ros/os-release", "/usr/lib/os-release"},
|
||||
{"/usr/share/ros/os-release", "/etc/os-release"},
|
||||
} {
|
||||
syscall.Unlink(link.newname)
|
||||
if err := os.Symlink(link.oldname, link.newname); err != nil {
|
||||
log.Error(err)
|
||||
@@ -182,7 +128,7 @@ func consoleInitFunc() error {
|
||||
proxyLines := []string{}
|
||||
for _, k := range []string{"http_proxy", "HTTP_PROXY", "https_proxy", "HTTPS_PROXY", "no_proxy", "NO_PROXY"} {
|
||||
if v, ok := cfg.Rancher.Environment[k]; ok {
|
||||
proxyLines = append(proxyLines, fmt.Sprintf("export %s=%q", k, v))
|
||||
proxyLines = append(proxyLines, fmt.Sprintf("export %s=%s", k, v))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,24 +197,11 @@ func generateRespawnConf(cmdline, user string, sshd, recovery bool) string {
|
||||
autologinBin = "/usr/bin/recovery"
|
||||
}
|
||||
|
||||
config := config.LoadConfig()
|
||||
|
||||
allowAutoLogin := true
|
||||
for _, d := range config.Rancher.Disable {
|
||||
if d == "autologin" {
|
||||
allowAutoLogin = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for i := 1; i < 7; i++ {
|
||||
tty := fmt.Sprintf("tty%d", i)
|
||||
if !istty(tty) {
|
||||
continue
|
||||
}
|
||||
|
||||
respawnConf.WriteString(gettyCmd)
|
||||
if allowAutoLogin && strings.Contains(cmdline, fmt.Sprintf("rancher.autologin=%s", tty)) {
|
||||
if strings.Contains(cmdline, fmt.Sprintf("rancher.autologin=%s", tty)) {
|
||||
respawnConf.WriteString(fmt.Sprintf(" -n -l %s -o %s:tty%d", autologinBin, user, i))
|
||||
}
|
||||
respawnConf.WriteString(fmt.Sprintf(" --noclear %s linux\n", tty))
|
||||
@@ -279,12 +212,8 @@ func generateRespawnConf(cmdline, user string, sshd, recovery bool) string {
|
||||
continue
|
||||
}
|
||||
|
||||
if !istty(tty) {
|
||||
continue
|
||||
}
|
||||
|
||||
respawnConf.WriteString(gettyCmd)
|
||||
if allowAutoLogin && strings.Contains(cmdline, fmt.Sprintf("rancher.autologin=%s", tty)) {
|
||||
if strings.Contains(cmdline, fmt.Sprintf("rancher.autologin=%s", tty)) {
|
||||
respawnConf.WriteString(fmt.Sprintf(" -n -l %s -o %s:%s", autologinBin, user, tty))
|
||||
}
|
||||
respawnConf.WriteString(fmt.Sprintf(" %s\n", tty))
|
||||
@@ -324,33 +253,37 @@ func writeRespawn(user string, sshd, recovery bool) error {
|
||||
}
|
||||
|
||||
func modifySshdConfig(cfg *config.CloudConfig) error {
|
||||
_, err := os.Stat(sshdTplFile)
|
||||
if err == nil {
|
||||
os.Remove(sshdFile)
|
||||
sshdTpl, err := template.ParseFiles(sshdTplFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.OpenFile(sshdFile, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
sshdConfig, err := ioutil.ReadFile("/etc/ssh/sshd_config")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sshdConfigString := string(sshdConfig)
|
||||
|
||||
config := map[string]string{}
|
||||
if cfg.Rancher.SSH.Port > 0 && cfg.Rancher.SSH.Port < 65355 {
|
||||
config["Port"] = strconv.Itoa(cfg.Rancher.SSH.Port)
|
||||
}
|
||||
if cfg.Rancher.SSH.ListenAddress != "" {
|
||||
config["ListenAddress"] = cfg.Rancher.SSH.ListenAddress
|
||||
}
|
||||
|
||||
return sshdTpl.Execute(f, config)
|
||||
} else if os.IsNotExist(err) {
|
||||
return nil
|
||||
modifiedLines := []string{
|
||||
"UseDNS no",
|
||||
"PermitRootLogin no",
|
||||
"ServerKeyBits 2048",
|
||||
"AllowGroups docker",
|
||||
}
|
||||
|
||||
return err
|
||||
if cfg.Rancher.SSH.Port > 0 && cfg.Rancher.SSH.Port < 65355 {
|
||||
modifiedLines = append(modifiedLines, fmt.Sprintf("Port %d", cfg.Rancher.SSH.Port))
|
||||
}
|
||||
if cfg.Rancher.SSH.ListenAddress != "" {
|
||||
modifiedLines = append(modifiedLines, fmt.Sprintf("ListenAddress %s", cfg.Rancher.SSH.ListenAddress))
|
||||
}
|
||||
|
||||
for _, item := range modifiedLines {
|
||||
match, err := regexp.Match("^"+item, sshdConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !match {
|
||||
sshdConfigString += fmt.Sprintf("%s\n", item)
|
||||
}
|
||||
}
|
||||
|
||||
return ioutil.WriteFile("/etc/ssh/sshd_config", []byte(sshdConfigString), 0644)
|
||||
}
|
||||
|
||||
func setupSSH(cfg *config.CloudConfig) error {
|
||||
@@ -397,10 +330,3 @@ func setupSSH(cfg *config.CloudConfig) error {
|
||||
|
||||
return os.MkdirAll("/var/run/sshd", 0644)
|
||||
}
|
||||
|
||||
func istty(name string) bool {
|
||||
if f, err := os.Open(fmt.Sprintf("/dev/%s", name)); err == nil {
|
||||
return terminal.IsTerminal(int(f.Fd()))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -3,9 +3,8 @@ package control
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
func devAction(c *cli.Context) error {
|
||||
|
||||
@@ -9,19 +9,15 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
dockerConf = "/var/lib/rancher/conf/docker"
|
||||
dockerDone = "/run/docker-done"
|
||||
dockerLog = "/var/log/docker.log"
|
||||
dockerCompletionLinkFile = "/usr/share/bash-completion/completions/docker"
|
||||
dockerCompletionFile = "/var/lib/rancher/engine/completion"
|
||||
dockerConf = "/var/lib/rancher/conf/docker"
|
||||
dockerDone = "/run/docker-done"
|
||||
dockerLog = "/var/log/docker.log"
|
||||
)
|
||||
|
||||
func dockerInitAction(c *cli.Context) error {
|
||||
@@ -33,12 +29,6 @@ func dockerInitAction(c *cli.Context) error {
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(dockerCompletionFile); err != nil {
|
||||
if _, err := os.Readlink(dockerCompletionLinkFile); err == nil {
|
||||
syscall.Unlink(dockerCompletionLinkFile)
|
||||
}
|
||||
}
|
||||
|
||||
dockerBin := ""
|
||||
dockerPaths := []string{
|
||||
"/usr/bin",
|
||||
@@ -85,22 +75,6 @@ func dockerInitAction(c *cli.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
cfg := config.LoadConfig()
|
||||
|
||||
for _, link := range symLinkEngineBinary() {
|
||||
syscall.Unlink(link.newname)
|
||||
if _, err := os.Stat(link.oldname); err == nil {
|
||||
if err := os.Symlink(link.oldname, link.newname); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = checkZfsBackingFS(cfg.Rancher.Docker.StorageDriver, cfg.Rancher.Docker.Graph)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"bash",
|
||||
"-c",
|
||||
|
||||
@@ -2,41 +2,28 @@ package control
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/cmd/control/service"
|
||||
"github.com/rancher/os/cmd/control/service/app"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/compose"
|
||||
"github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/pkg/util/network"
|
||||
"github.com/rancher/os/pkg/util/versions"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/docker/docker/reference"
|
||||
"github.com/docker/engine-api/types"
|
||||
"github.com/docker/engine-api/types/filters"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/project/options"
|
||||
composeYaml "github.com/docker/libcompose/yaml"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
"github.com/rancher/os/cmd/control/service"
|
||||
"github.com/rancher/os/compose"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
"github.com/rancher/os/util/network"
|
||||
)
|
||||
|
||||
func engineSubcommands() []cli.Command {
|
||||
return []cli.Command{
|
||||
{
|
||||
Name: "switch",
|
||||
Usage: "switch user Docker engine without a reboot",
|
||||
Usage: "switch Docker engine without a reboot",
|
||||
Action: engineSwitch,
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
@@ -49,74 +36,14 @@ func engineSubcommands() []cli.Command {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "create",
|
||||
Usage: "create Dind engine without a reboot",
|
||||
Description: "must switch user docker to 17.12.1 or earlier if using Dind",
|
||||
ArgsUsage: "<name>",
|
||||
Before: preFlightValidate,
|
||||
Action: engineCreate,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "version, v",
|
||||
Value: config.DefaultDind,
|
||||
Usage: fmt.Sprintf("set the version for the engine, %s are available", config.SupportedDinds),
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "network",
|
||||
Usage: "set the network for the engine",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "fixed-ip",
|
||||
Usage: "set the fixed ip for the engine",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "ssh-port",
|
||||
Usage: "set the ssh port for the engine",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "authorized-keys",
|
||||
Usage: "set the ssh authorized_keys absolute path for the engine",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "rm",
|
||||
Usage: "remove Dind engine without a reboot",
|
||||
ArgsUsage: "<name>",
|
||||
Before: func(c *cli.Context) error {
|
||||
if len(c.Args()) != 1 {
|
||||
return errors.New("Must specify exactly one Docker engine to remove")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Action: dindEngineRemove,
|
||||
Flags: []cli.Flag{
|
||||
cli.IntFlag{
|
||||
Name: "timeout,t",
|
||||
Usage: "specify a shutdown timeout in seconds",
|
||||
Value: 10,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "force, f",
|
||||
Usage: "do not prompt for input",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "enable",
|
||||
Usage: "set user Docker engine to be switched on next reboot",
|
||||
Usage: "set Docker engine to be switched on next reboot",
|
||||
Action: engineEnable,
|
||||
},
|
||||
{
|
||||
Name: "list",
|
||||
Usage: "list available Docker engines (include the Dind engines)",
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "update, u",
|
||||
Usage: "update engine cache",
|
||||
},
|
||||
},
|
||||
Name: "list",
|
||||
Usage: "list available Docker engines",
|
||||
Action: engineList,
|
||||
},
|
||||
}
|
||||
@@ -155,108 +82,6 @@ func engineSwitch(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func engineCreate(c *cli.Context) error {
|
||||
name := c.Args()[0]
|
||||
version := c.String("version")
|
||||
sshPort, _ := strconv.Atoi(c.String("ssh-port"))
|
||||
if sshPort <= 0 {
|
||||
sshPort = randomSSHPort()
|
||||
}
|
||||
authorizedKeys := c.String("authorized-keys")
|
||||
network := c.String("network")
|
||||
fixedIP := c.String("fixed-ip")
|
||||
|
||||
// generate & create engine compose
|
||||
err := generateEngineCompose(name, version, sshPort, authorizedKeys, network, fixedIP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// stage engine service
|
||||
cfg := config.LoadConfig()
|
||||
var enabledServices []string
|
||||
if val, ok := cfg.Rancher.ServicesInclude[name]; !ok || !val {
|
||||
cfg.Rancher.ServicesInclude[name] = true
|
||||
enabledServices = append(enabledServices, name)
|
||||
}
|
||||
|
||||
if len(enabledServices) > 0 {
|
||||
if err := compose.StageServices(cfg, enabledServices...); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := config.Set("rancher.services_include", cfg.Rancher.ServicesInclude); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// generate engine script
|
||||
err = util.GenerateDindEngineScript(name)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dindEngineRemove(c *cli.Context) error {
|
||||
if !c.Bool("force") {
|
||||
if !yes("Continue") {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// app.ProjectDelete needs to use this flag
|
||||
// Allow deletion of the Dind engine
|
||||
c.Set("force", "true")
|
||||
// Remove volumes associated with the Dind engine container
|
||||
c.Set("v", "true")
|
||||
|
||||
name := c.Args()[0]
|
||||
cfg := config.LoadConfig()
|
||||
p, err := compose.GetProject(cfg, true, false)
|
||||
if err != nil {
|
||||
log.Fatalf("Get project failed: %v", err)
|
||||
}
|
||||
|
||||
// 1. service stop
|
||||
err = app.ProjectStop(p, c)
|
||||
if err != nil {
|
||||
log.Fatalf("Stop project service failed: %v", err)
|
||||
}
|
||||
|
||||
// 2. service delete
|
||||
err = app.ProjectDelete(p, c)
|
||||
if err != nil {
|
||||
log.Fatalf("Delete project service failed: %v", err)
|
||||
}
|
||||
|
||||
// 3. service delete
|
||||
if _, ok := cfg.Rancher.ServicesInclude[name]; !ok {
|
||||
log.Fatalf("Failed to found enabled service %s", name)
|
||||
}
|
||||
|
||||
delete(cfg.Rancher.ServicesInclude, name)
|
||||
|
||||
if err = config.Set("rancher.services_include", cfg.Rancher.ServicesInclude); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 4. remove service from file
|
||||
err = RemoveEngineFromCompose(name)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 5. remove dind engine script
|
||||
err = util.RemoveDindEngineScript(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func engineEnable(c *cli.Context) error {
|
||||
if len(c.Args()) != 1 {
|
||||
log.Fatal("Must specify exactly one Docker engine to enable")
|
||||
@@ -279,7 +104,7 @@ func engineEnable(c *cli.Context) error {
|
||||
|
||||
func engineList(c *cli.Context) error {
|
||||
cfg := config.LoadConfig()
|
||||
engines := availableEngines(cfg, c.Bool("update"))
|
||||
engines := availableEngines(cfg)
|
||||
currentEngine := CurrentEngine()
|
||||
|
||||
for _, engine := range engines {
|
||||
@@ -292,50 +117,17 @@ func engineList(c *cli.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
// check the dind container
|
||||
client, err := docker.NewSystemClient()
|
||||
if err != nil {
|
||||
log.Warnf("Failed to detect dind: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
filter := filters.NewArgs()
|
||||
filter.Add("label", config.UserDockerLabel)
|
||||
opts := types.ContainerListOptions{
|
||||
All: true,
|
||||
Filter: filter,
|
||||
}
|
||||
containers, err := client.ContainerList(context.Background(), opts)
|
||||
if err != nil {
|
||||
log.Warnf("Failed to detect dind: %v", err)
|
||||
return nil
|
||||
}
|
||||
for _, c := range containers {
|
||||
if c.State == "running" {
|
||||
fmt.Printf("enabled %s\n", c.Labels[config.UserDockerLabel])
|
||||
} else {
|
||||
fmt.Printf("disabled %s\n", c.Labels[config.UserDockerLabel])
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateEngine(engine string, cfg *config.CloudConfig) {
|
||||
engines := availableEngines(cfg, false)
|
||||
engines := availableEngines(cfg)
|
||||
if !service.IsLocalOrURL(engine) && !util.Contains(engines, engine) {
|
||||
log.Fatalf("%s is not a valid engine", engine)
|
||||
}
|
||||
}
|
||||
|
||||
func availableEngines(cfg *config.CloudConfig, update bool) []string {
|
||||
if update {
|
||||
err := network.UpdateCaches(cfg.Rancher.Repositories.ToArray(), "engines")
|
||||
if err != nil {
|
||||
log.Debugf("Failed to update engine caches: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
func availableEngines(cfg *config.CloudConfig) []string {
|
||||
engines, err := network.GetEngines(cfg.Rancher.Repositories.ToArray())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -365,14 +157,8 @@ func CurrentEngine() (engine string) {
|
||||
}
|
||||
if t, ok := image.(reference.NamedTagged); ok {
|
||||
tag := t.Tag()
|
||||
|
||||
// compatible with some patch image tags, such as 17.12.1-1,17.06.2-1,...
|
||||
tag = strings.SplitN(tag, "-", 2)[0]
|
||||
|
||||
if !strings.HasPrefix(tag, "1.") && versions.LessThan(tag, "18.09.0") {
|
||||
// >= 18.09.0, docker-<version>
|
||||
// < 18.09.0 and >= 16.03, docker-<version>-ce
|
||||
// < 17.03, docker-<version>
|
||||
if !strings.HasPrefix(tag, "1.") {
|
||||
// TODO: this assumes we only do Docker ce :/
|
||||
tag = tag + "-ce"
|
||||
}
|
||||
return "docker-" + tag
|
||||
@@ -380,210 +166,3 @@ func CurrentEngine() (engine string) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func preFlightValidate(c *cli.Context) error {
|
||||
if len(c.Args()) != 1 {
|
||||
return errors.New("Must specify one engine name")
|
||||
}
|
||||
name := c.Args()[0]
|
||||
if name == "" {
|
||||
return errors.New("Must specify one engine name")
|
||||
}
|
||||
|
||||
version := c.String("version")
|
||||
if version == "" {
|
||||
return errors.New("Must specify one engine version")
|
||||
}
|
||||
|
||||
authorizedKeys := c.String("authorized-keys")
|
||||
if authorizedKeys != "" {
|
||||
if _, err := os.Stat(authorizedKeys); os.IsNotExist(err) {
|
||||
return errors.New("The authorized-keys should be an exist file, recommended to put in the /opt or /var/lib/rancher directory")
|
||||
}
|
||||
}
|
||||
|
||||
network := c.String("network")
|
||||
if network == "" {
|
||||
return errors.New("Must specify network")
|
||||
}
|
||||
|
||||
userDefineNetwork, err := CheckUserDefineNetwork(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fixedIP := c.String("fixed-ip")
|
||||
if fixedIP == "" {
|
||||
return errors.New("Must specify fix ip")
|
||||
}
|
||||
|
||||
err = CheckUserDefineIPv4Address(fixedIP, *userDefineNetwork)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isVersionMatch := false
|
||||
for _, v := range config.SupportedDinds {
|
||||
if v == version {
|
||||
isVersionMatch = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isVersionMatch {
|
||||
return errors.Errorf("Engine version not supported only %v are supported", config.SupportedDinds)
|
||||
}
|
||||
|
||||
if c.String("ssh-port") != "" {
|
||||
port, err := strconv.Atoi(c.String("ssh-port"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to convert ssh port to Int")
|
||||
}
|
||||
if port > 0 {
|
||||
addr, err := net.ResolveTCPAddr("tcp", "localhost:"+strconv.Itoa(port))
|
||||
if err != nil {
|
||||
return errors.Errorf("Failed to resolve tcp addr: %v", err)
|
||||
}
|
||||
l, err := net.ListenTCP("tcp", addr)
|
||||
if err != nil {
|
||||
return errors.Errorf("Failed to listen tcp: %v", err)
|
||||
}
|
||||
defer l.Close()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func randomSSHPort() int {
|
||||
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
|
||||
if err != nil {
|
||||
log.Errorf("Failed to resolve tcp addr: %v", err)
|
||||
return 0
|
||||
}
|
||||
|
||||
l, err := net.ListenTCP("tcp", addr)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
defer l.Close()
|
||||
return l.Addr().(*net.TCPAddr).Port
|
||||
}
|
||||
|
||||
func generateEngineCompose(name, version string, sshPort int, authorizedKeys, network, fixedIP string) error {
|
||||
if err := os.MkdirAll(path.Dir(config.MultiDockerConfFile), 0700); err != nil && !os.IsExist(err) {
|
||||
log.Errorf("Failed to create directory for file %s: %v", config.MultiDockerConfFile, err)
|
||||
return err
|
||||
}
|
||||
|
||||
composeConfigs := map[string]composeConfig.ServiceConfigV1{}
|
||||
|
||||
if _, err := os.Stat(config.MultiDockerConfFile); err == nil {
|
||||
// read from engine compose
|
||||
bytes, err := ioutil.ReadFile(config.MultiDockerConfFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = yaml.Unmarshal(bytes, &composeConfigs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(config.MultiDockerDataDir+"/"+name, 0700); err != nil && !os.IsExist(err) {
|
||||
log.Errorf("Failed to create directory for file %s: %v", config.MultiDockerDataDir+"/"+name, err)
|
||||
return err
|
||||
}
|
||||
|
||||
volumes := []string{
|
||||
"/lib/modules:/lib/modules",
|
||||
config.MultiDockerDataDir + "/" + name + ":" + config.MultiDockerDataDir + "/" + name,
|
||||
}
|
||||
if authorizedKeys != "" {
|
||||
volumes = append(volumes, authorizedKeys+":/root/.ssh/authorized_keys")
|
||||
}
|
||||
|
||||
composeConfigs[name] = composeConfig.ServiceConfigV1{
|
||||
Image: "${REGISTRY_DOMAIN}/" + version,
|
||||
Restart: "always",
|
||||
Privileged: true,
|
||||
Net: network,
|
||||
Ports: []string{strconv.Itoa(sshPort) + ":22"},
|
||||
Volumes: volumes,
|
||||
VolumesFrom: []string{},
|
||||
Command: composeYaml.Command{
|
||||
"--storage-driver=overlay2",
|
||||
"--data-root=" + config.MultiDockerDataDir + "/" + name,
|
||||
"--host=unix://" + config.MultiDockerDataDir + "/" + name + "/docker-" + name + ".sock",
|
||||
},
|
||||
Labels: composeYaml.SliceorMap{
|
||||
"io.rancher.os.scope": "system",
|
||||
"io.rancher.os.after": "console",
|
||||
config.UserDockerLabel: name,
|
||||
config.UserDockerNetLabel: network,
|
||||
config.UserDockerFIPLabel: fixedIP,
|
||||
},
|
||||
}
|
||||
|
||||
bytes, err := yaml.Marshal(composeConfigs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(config.MultiDockerConfFile, bytes, 0640)
|
||||
}
|
||||
|
||||
func RemoveEngineFromCompose(name string) error {
|
||||
composeConfigs := map[string]composeConfig.ServiceConfigV1{}
|
||||
|
||||
if _, err := os.Stat(config.MultiDockerConfFile); err == nil {
|
||||
// read from engine compose
|
||||
bytes, err := ioutil.ReadFile(config.MultiDockerConfFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = yaml.Unmarshal(bytes, &composeConfigs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
delete(composeConfigs, name)
|
||||
|
||||
bytes, err := yaml.Marshal(composeConfigs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(config.MultiDockerConfFile, bytes, 0640)
|
||||
}
|
||||
|
||||
func CheckUserDefineNetwork(name string) (*types.NetworkResource, error) {
|
||||
systemClient, err := docker.NewSystemClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
networks, err := systemClient.NetworkList(context.Background(), types.NetworkListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, network := range networks {
|
||||
if network.Name == name {
|
||||
return &network, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("Failed to found the user define network: %s", name)
|
||||
}
|
||||
|
||||
func CheckUserDefineIPv4Address(ipv4 string, network types.NetworkResource) error {
|
||||
for _, config := range network.IPAM.Config {
|
||||
_, ipnet, _ := net.ParseCIDR(config.Subnet)
|
||||
if ipnet.Contains(net.ParseIP(ipv4)) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errors.Errorf("IP %s is not in the specified cidr", ipv4)
|
||||
}
|
||||
|
||||
@@ -5,14 +5,14 @@ import (
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/log"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/rancher/os/cmd/cloudinitexecute"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"golang.org/x/net/context"
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -6,10 +6,9 @@ import (
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
func envAction(c *cli.Context) error {
|
||||
|
||||
@@ -11,17 +11,19 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/cmd/control/install"
|
||||
"github.com/rancher/os/cmd/power"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/dfs" // TODO: move CopyFile into util or something.
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rancher/catalog-service/utils/version"
|
||||
"github.com/rancher/os/cmd/control/install"
|
||||
"github.com/rancher/os/cmd/power"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/dfs" // TODO: move CopyFile into util or something.
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
var installCommand = cli.Command{
|
||||
@@ -85,10 +87,6 @@ var installCommand = cli.Command{
|
||||
Name: "kexec, k",
|
||||
Usage: "reboot using kexec",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "save, s",
|
||||
Usage: "save services and images for next booting",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
Usage: "Run installer with debug output",
|
||||
@@ -179,13 +177,7 @@ func installAction(c *cli.Context) error {
|
||||
cloudConfig = uc
|
||||
}
|
||||
|
||||
savedImages := []string{}
|
||||
if c.Bool("save") && cloudConfig != "" && installType != "upgrade" {
|
||||
savedImages = install.GetCacheImageList(cloudConfig, cfg)
|
||||
log.Debugf("Will cache these images: %s", savedImages)
|
||||
}
|
||||
|
||||
if err := runInstall(image, installType, cloudConfig, device, partition, statedir, kappend, force, kexec, isoinstallerloaded, debug, savedImages); err != nil {
|
||||
if err := runInstall(image, installType, cloudConfig, device, partition, statedir, kappend, force, kexec, isoinstallerloaded, debug); err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Fatal("Failed to run install")
|
||||
return err
|
||||
}
|
||||
@@ -198,7 +190,7 @@ func installAction(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func runInstall(image, installType, cloudConfig, device, partition, statedir, kappend string, force, kexec, isoinstallerloaded, debug bool, savedImages []string) error {
|
||||
func runInstall(image, installType, cloudConfig, device, partition, statedir, kappend string, force, kexec, isoinstallerloaded, debug bool) error {
|
||||
fmt.Printf("Installing from %s\n", image)
|
||||
|
||||
if !force {
|
||||
@@ -207,6 +199,46 @@ func runInstall(image, installType, cloudConfig, device, partition, statedir, ka
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
diskType := "msdos"
|
||||
|
||||
if installType == "gptsyslinux" {
|
||||
diskType = "gpt"
|
||||
}
|
||||
|
||||
// Versions before 0.8.0-rc3 use the old calling convention (from the lay-down-os shell script)
|
||||
imageVersion := strings.Split(image, ":")[1]
|
||||
if version.GreaterThan("v0.8.0-rc3", imageVersion) {
|
||||
log.Infof("user specified to install pre v0.8.0: %s", image)
|
||||
imageVersion = strings.Replace(imageVersion, "-", ".", -1)
|
||||
vArray := strings.Split(imageVersion, ".")
|
||||
if len(vArray) >= 2 {
|
||||
v, _ := strconv.ParseFloat(vArray[0]+"."+vArray[1], 32)
|
||||
if v < 0.8 || imageVersion == "0.8.0-rc1" {
|
||||
log.Infof("starting installer container for %s", image)
|
||||
if installType == "generic" ||
|
||||
installType == "syslinux" ||
|
||||
installType == "gptsyslinux" {
|
||||
cmd := exec.Command("system-docker", "run", "--net=host", "--privileged", "--volumes-from=all-volumes",
|
||||
"--entrypoint=/scripts/set-disk-partitions", image, device, diskType)
|
||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
cmd := exec.Command("system-docker", "run", "--net=host", "--privileged", "--volumes-from=user-volumes",
|
||||
"--volumes-from=command-volumes", image, "-d", device, "-t", installType, "-c", cloudConfig,
|
||||
"-a", kappend)
|
||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if _, err := os.Stat("/usr/bin/system-docker"); os.IsNotExist(err) {
|
||||
//if err := os.Symlink("/usr/bin/ros", "/usr/bin/system-docker"); err != nil {
|
||||
//log.Errorf("ln error %s", err)
|
||||
//}
|
||||
//}
|
||||
|
||||
useIso := false
|
||||
// --isoinstallerloaded is used if the ros has created the installer container from and image that was on the booted iso
|
||||
@@ -283,18 +315,15 @@ func runInstall(image, installType, cloudConfig, device, partition, statedir, ka
|
||||
if statedir != "" {
|
||||
installerCmd = append(installerCmd, "--statedir", statedir)
|
||||
}
|
||||
if len(savedImages) > 0 {
|
||||
installerCmd = append(installerCmd, "--save")
|
||||
}
|
||||
|
||||
// TODO: mount at /mnt for shared mount?
|
||||
if useIso {
|
||||
util.Unmount("/bootiso")
|
||||
}
|
||||
|
||||
cmd := exec.Command("system-docker", installerCmd...)
|
||||
log.Debugf("Run(%v)", cmd)
|
||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
}
|
||||
@@ -319,7 +348,7 @@ func runInstall(image, installType, cloudConfig, device, partition, statedir, ka
|
||||
device = "/host" + device
|
||||
//# TODO: Change this to a number so that users can specify.
|
||||
//# Will need to make it so that our builds and packer APIs remain consistent.
|
||||
partition = install.GetDefaultPartition(device)
|
||||
partition = device + "1" //${partition:=${device}1}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,10 +377,6 @@ func runInstall(image, installType, cloudConfig, device, partition, statedir, ka
|
||||
return err
|
||||
}
|
||||
|
||||
if len(savedImages) > 0 {
|
||||
return install.RunCacheScript(partition, savedImages)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -447,7 +472,7 @@ func layDownOS(image, installType, cloudConfig, device, partition, statedir, kap
|
||||
case "generic":
|
||||
log.Debugf("formatAndMount")
|
||||
var err error
|
||||
device, _, err = formatAndMount(baseName, device, partition)
|
||||
device, partition, err = formatAndMount(baseName, device, partition)
|
||||
if err != nil {
|
||||
log.Errorf("formatAndMount %s", err)
|
||||
return err
|
||||
@@ -464,7 +489,7 @@ func layDownOS(image, installType, cloudConfig, device, partition, statedir, kap
|
||||
}
|
||||
case "arm":
|
||||
var err error
|
||||
_, _, err = formatAndMount(baseName, device, partition)
|
||||
device, partition, err = formatAndMount(baseName, device, partition)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -474,7 +499,7 @@ func layDownOS(image, installType, cloudConfig, device, partition, statedir, kap
|
||||
case "amazon-ebs-hvm":
|
||||
CONSOLE = "ttyS0"
|
||||
var err error
|
||||
device, _, err = formatAndMount(baseName, device, partition)
|
||||
device, partition, err = formatAndMount(baseName, device, partition)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -486,7 +511,7 @@ func layDownOS(image, installType, cloudConfig, device, partition, statedir, kap
|
||||
case "googlecompute":
|
||||
CONSOLE = "ttyS0"
|
||||
var err error
|
||||
device, _, err = formatAndMount(baseName, device, partition)
|
||||
device, partition, err = formatAndMount(baseName, device, partition)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -494,7 +519,7 @@ func layDownOS(image, installType, cloudConfig, device, partition, statedir, kap
|
||||
seedData(baseName, cloudConfig, FILES)
|
||||
case "noformat":
|
||||
var err error
|
||||
device, _, err = install.MountDevice(baseName, device, partition, false)
|
||||
device, partition, err = install.MountDevice(baseName, device, partition, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -502,14 +527,9 @@ func layDownOS(image, installType, cloudConfig, device, partition, statedir, kap
|
||||
if err := os.MkdirAll(filepath.Join(baseName, statedir), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
err = seedData(baseName, cloudConfig, FILES)
|
||||
if err != nil {
|
||||
log.Errorf("seedData %s", err)
|
||||
return err
|
||||
}
|
||||
case "raid":
|
||||
var err error
|
||||
device, _, err = install.MountDevice(baseName, device, partition, false)
|
||||
device, partition, err = install.MountDevice(baseName, device, partition, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -517,7 +537,7 @@ func layDownOS(image, installType, cloudConfig, device, partition, statedir, kap
|
||||
case "bootstrap":
|
||||
CONSOLE = "ttyS0"
|
||||
var err error
|
||||
_, _, err = install.MountDevice(baseName, device, partition, true)
|
||||
device, partition, err = install.MountDevice(baseName, device, partition, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -527,7 +547,7 @@ func layDownOS(image, installType, cloudConfig, device, partition, statedir, kap
|
||||
fallthrough
|
||||
case "upgrade":
|
||||
var err error
|
||||
device, _, err = install.MountDevice(baseName, device, partition, false)
|
||||
device, partition, err = install.MountDevice(baseName, device, partition, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -540,20 +560,20 @@ func layDownOS(image, installType, cloudConfig, device, partition, statedir, kap
|
||||
kernelArgs = kernelArgs + " console=" + CONSOLE
|
||||
|
||||
if kappend == "" {
|
||||
preservedAppend, _ := ioutil.ReadFile(filepath.Join(baseName, config.BootDir, "append"))
|
||||
preservedAppend, _ := ioutil.ReadFile(filepath.Join(baseName, install.BootDir+"append"))
|
||||
kappend = string(preservedAppend)
|
||||
} else {
|
||||
ioutil.WriteFile(filepath.Join(baseName, config.BootDir, "append"), []byte(kappend), 0644)
|
||||
ioutil.WriteFile(filepath.Join(baseName, install.BootDir+"append"), []byte(kappend), 0644)
|
||||
}
|
||||
|
||||
if installType == "amazon-ebs-pv" {
|
||||
menu := install.BootVars{
|
||||
BaseName: baseName,
|
||||
BootDir: config.BootDir,
|
||||
BootDir: install.BootDir,
|
||||
Timeout: 0,
|
||||
Fallback: 0, // need to be conditional on there being a 'rollback'?
|
||||
Entries: []install.MenuEntry{
|
||||
install.MenuEntry{"RancherOS-current", config.BootDir, VERSION, kernelArgs, kappend},
|
||||
install.MenuEntry{"RancherOS-current", install.BootDir, VERSION, kernelArgs, kappend},
|
||||
},
|
||||
}
|
||||
install.PvGrubConfig(menu)
|
||||
@@ -567,7 +587,7 @@ func layDownOS(image, installType, cloudConfig, device, partition, statedir, kap
|
||||
log.Debugf("installRancher done")
|
||||
|
||||
if kexec {
|
||||
power.Kexec(false, filepath.Join(baseName, config.BootDir), kernelArgs+" "+kappend)
|
||||
power.Kexec(false, filepath.Join(baseName, install.BootDir), kernelArgs+" "+kappend)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -581,42 +601,12 @@ func seedData(baseName, cloudData string, files []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
stateSeedDir := "state_seed"
|
||||
cloudConfigBase := "/var/lib/rancher/conf/cloud-config.d"
|
||||
cloudConfigDir := ""
|
||||
|
||||
// If there is a separate boot partition, cloud-config should be written to RANCHER_STATE partition.
|
||||
bootPartition, _, err := util.Blkid("RANCHER_BOOT")
|
||||
if err != nil {
|
||||
log.Errorf("Failed to run blkid: %s", err)
|
||||
}
|
||||
if bootPartition != "" {
|
||||
stateSeedFullPath := filepath.Join(baseName, stateSeedDir)
|
||||
if err = os.MkdirAll(stateSeedFullPath, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer util.Unmount(stateSeedFullPath)
|
||||
|
||||
statePartition := install.GetStatePartition()
|
||||
cmd := exec.Command("mount", statePartition, stateSeedFullPath)
|
||||
//cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||
log.Debugf("seedData: mount %s to %s", statePartition, stateSeedFullPath)
|
||||
if err = cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cloudConfigDir = filepath.Join(baseName, stateSeedDir, cloudConfigBase)
|
||||
} else {
|
||||
cloudConfigDir = filepath.Join(baseName, cloudConfigBase)
|
||||
}
|
||||
|
||||
if err = os.MkdirAll(cloudConfigDir, 0700); err != nil {
|
||||
if err = os.MkdirAll(filepath.Join(baseName, "/var/lib/rancher/conf/cloud-config.d"), 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(cloudData, "empty.yml") {
|
||||
if err = dfs.CopyFile(cloudData, cloudConfigDir, filepath.Base(cloudData)); err != nil {
|
||||
if err = dfs.CopyFile(cloudData, baseName+"/var/lib/rancher/conf/cloud-config.d/", filepath.Base(cloudData)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -811,7 +801,7 @@ func setBootable(device, diskType string) error {
|
||||
func upgradeBootloader(device, baseName, diskType string) error {
|
||||
log.Debugf("start upgradeBootloader")
|
||||
|
||||
grubDir := filepath.Join(baseName, config.BootDir, "grub")
|
||||
grubDir := filepath.Join(baseName, install.BootDir+"grub")
|
||||
if _, err := os.Stat(grubDir); os.IsNotExist(err) {
|
||||
log.Debugf("%s does not exist - no need to upgrade bootloader", grubDir)
|
||||
// we've already upgraded
|
||||
@@ -819,12 +809,12 @@ func upgradeBootloader(device, baseName, diskType string) error {
|
||||
return nil
|
||||
}
|
||||
// deal with systems which were previously upgraded, then rolled back, and are now being re-upgraded
|
||||
grubBackup := filepath.Join(baseName, config.BootDir, "grub_backup")
|
||||
grubBackup := filepath.Join(baseName, install.BootDir+"grub_backup")
|
||||
if err := os.RemoveAll(grubBackup); err != nil {
|
||||
log.Errorf("RemoveAll (%s): %s", grubBackup, err)
|
||||
return err
|
||||
}
|
||||
backupSyslinuxDir := filepath.Join(baseName, config.BootDir, "syslinux_backup")
|
||||
backupSyslinuxDir := filepath.Join(baseName, install.BootDir+"syslinux_backup")
|
||||
if _, err := os.Stat(backupSyslinuxDir); !os.IsNotExist(err) {
|
||||
backupSyslinuxLdlinuxSys := filepath.Join(backupSyslinuxDir, "ldlinux.sys")
|
||||
if _, err := os.Stat(backupSyslinuxLdlinuxSys); !os.IsNotExist(err) {
|
||||
@@ -847,7 +837,7 @@ func upgradeBootloader(device, baseName, diskType string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
syslinuxDir := filepath.Join(baseName, config.BootDir, "syslinux")
|
||||
syslinuxDir := filepath.Join(baseName, install.BootDir+"syslinux")
|
||||
// it seems that v0.5.0 didn't have a syslinux dir, while 0.7 does
|
||||
if _, err := os.Stat(syslinuxDir); !os.IsNotExist(err) {
|
||||
if err := os.Rename(syslinuxDir, backupSyslinuxDir); err != nil {
|
||||
@@ -868,15 +858,15 @@ func upgradeBootloader(device, baseName, diskType string) error {
|
||||
|
||||
cfg = strings.Replace(cfg, "current", "previous", -1)
|
||||
// TODO consider removing the APPEND line - as the global.cfg should have the same result
|
||||
ioutil.WriteFile(filepath.Join(baseName, config.BootDir, "linux-current.cfg"), []byte(cfg), 0644)
|
||||
ioutil.WriteFile(filepath.Join(baseName, install.BootDir, "linux-current.cfg"), []byte(cfg), 0644)
|
||||
|
||||
lines := strings.Split(cfg, "\n")
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasPrefix(line, "APPEND") {
|
||||
log.Errorf("write new (%s) %s", filepath.Join(baseName, config.BootDir, "global.cfg"), err)
|
||||
log.Errorf("write new (%s) %s", filepath.Join(baseName, install.BootDir, "global.cfg"), err)
|
||||
// TODO: need to append any extra's the user specified
|
||||
ioutil.WriteFile(filepath.Join(baseName, config.BootDir, "global.cfg"), []byte(cfg), 0644)
|
||||
ioutil.WriteFile(filepath.Join(baseName, install.BootDir, "global.cfg"), []byte(cfg), 0644)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -937,7 +927,7 @@ func installSyslinux(device, baseName, diskType string) error {
|
||||
}
|
||||
}
|
||||
|
||||
sysLinuxDir := filepath.Join(baseName, config.BootDir, "syslinux")
|
||||
sysLinuxDir := filepath.Join(baseName, install.BootDir, "syslinux")
|
||||
if err := os.MkdirAll(sysLinuxDir, 0755); err != nil {
|
||||
log.Errorf("MkdirAll(%s)): %s", sysLinuxDir, err)
|
||||
//return err
|
||||
@@ -995,12 +985,12 @@ func installRancher(baseName, VERSION, DIST, kappend string) (string, error) {
|
||||
log.Debugf("installRancher")
|
||||
|
||||
// detect if there already is a linux-current.cfg, if so, move it to linux-previous.cfg,
|
||||
currentCfg := filepath.Join(baseName, config.BootDir, "linux-current.cfg")
|
||||
currentCfg := filepath.Join(baseName, install.BootDir, "linux-current.cfg")
|
||||
if _, err := os.Stat(currentCfg); !os.IsNotExist(err) {
|
||||
existingCfg := filepath.Join(DIST, "linux-current.cfg")
|
||||
// only remove previous if there is a change to the current
|
||||
if different(currentCfg, existingCfg) {
|
||||
previousCfg := filepath.Join(baseName, config.BootDir, "linux-previous.cfg")
|
||||
previousCfg := filepath.Join(baseName, install.BootDir, "linux-previous.cfg")
|
||||
if _, err := os.Stat(previousCfg); !os.IsNotExist(err) {
|
||||
if err := os.Remove(previousCfg); err != nil {
|
||||
return currentCfg, err
|
||||
@@ -1022,7 +1012,7 @@ func installRancher(baseName, VERSION, DIST, kappend string) (string, error) {
|
||||
if file.Name() == "global.cfg" {
|
||||
overwrite = false
|
||||
}
|
||||
if err := dfs.CopyFileOverwrite(filepath.Join(DIST, file.Name()), filepath.Join(baseName, config.BootDir), file.Name(), overwrite); err != nil {
|
||||
if err := dfs.CopyFileOverwrite(filepath.Join(DIST, file.Name()), filepath.Join(baseName, install.BootDir), file.Name(), overwrite); err != nil {
|
||||
log.Errorf("copy %s: %s", file.Name(), err)
|
||||
//return err
|
||||
}
|
||||
@@ -1030,7 +1020,7 @@ func installRancher(baseName, VERSION, DIST, kappend string) (string, error) {
|
||||
|
||||
// the general INCLUDE syslinuxcfg
|
||||
isolinuxFile := filepath.Join(DIST, "isolinux", "isolinux.cfg")
|
||||
syslinuxDir := filepath.Join(baseName, config.BootDir, "syslinux")
|
||||
syslinuxDir := filepath.Join(baseName, install.BootDir, "syslinux")
|
||||
if err := dfs.CopyFileOverwrite(isolinuxFile, syslinuxDir, "syslinux.cfg", true); err != nil {
|
||||
log.Errorf("copy global syslinux.cfgS%s: %s", "syslinux.cfg", err)
|
||||
//return err
|
||||
@@ -1040,7 +1030,7 @@ func installRancher(baseName, VERSION, DIST, kappend string) (string, error) {
|
||||
}
|
||||
|
||||
// The global.cfg INCLUDE - useful for over-riding the APPEND line
|
||||
globalFile := filepath.Join(baseName, config.BootDir, "global.cfg")
|
||||
globalFile := filepath.Join(filepath.Join(baseName, install.BootDir), "global.cfg")
|
||||
if _, err := os.Stat(globalFile); !os.IsNotExist(err) {
|
||||
err := ioutil.WriteFile(globalFile, []byte("APPEND "+kappend), 0644)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
func RunGrub(baseName, device string) error {
|
||||
|
||||
@@ -7,10 +7,12 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const BootDir = "boot/"
|
||||
|
||||
type MenuEntry struct {
|
||||
Name, BootDir, Version, KernelArgs, Append string
|
||||
}
|
||||
@@ -44,15 +46,27 @@ func MountDevice(baseName, device, partition string, raw bool) (string, string,
|
||||
//rootfs := partition
|
||||
// Don't use ResolveDevice - it can fail, whereas `blkid -L LABEL` works more often
|
||||
|
||||
cfg := config.LoadConfig()
|
||||
d, _, err := util.Blkid("RANCHER_BOOT")
|
||||
if err != nil {
|
||||
log.Errorf("Failed to run blkid: %s", err)
|
||||
}
|
||||
if d != "" {
|
||||
partition = d
|
||||
baseName = filepath.Join(baseName, config.BootDir)
|
||||
baseName = filepath.Join(baseName, BootDir)
|
||||
} else {
|
||||
partition = GetStatePartition()
|
||||
if dev := util.ResolveDevice(cfg.Rancher.State.Dev); dev != "" {
|
||||
// try the rancher.state.dev setting
|
||||
partition = dev
|
||||
} else {
|
||||
d, _, err := util.Blkid("RANCHER_STATE")
|
||||
if err != nil {
|
||||
log.Errorf("Failed to run blkid: %s", err)
|
||||
}
|
||||
if d != "" {
|
||||
partition = d
|
||||
}
|
||||
}
|
||||
}
|
||||
cmd := exec.Command("lsblk", "-no", "pkname", partition)
|
||||
log.Debugf("Run(%v)", cmd)
|
||||
@@ -68,24 +82,3 @@ func MountDevice(baseName, device, partition string, raw bool) (string, string,
|
||||
log.Debugf("mountdevice return2 -> d: %s, p: %s", device, partition)
|
||||
return device, partition, cmd.Run()
|
||||
}
|
||||
|
||||
func GetStatePartition() string {
|
||||
cfg := config.LoadConfig()
|
||||
|
||||
if dev := util.ResolveDevice(cfg.Rancher.State.Dev); dev != "" {
|
||||
// try the rancher.state.dev setting
|
||||
return dev
|
||||
}
|
||||
d, _, err := util.Blkid("RANCHER_STATE")
|
||||
if err != nil {
|
||||
log.Errorf("Failed to run blkid: %s", err)
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func GetDefaultPartition(device string) string {
|
||||
if strings.Contains(device, "nvme") {
|
||||
return device + "p1"
|
||||
}
|
||||
return device + "1"
|
||||
}
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
package install
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/pkg/util/network"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
)
|
||||
|
||||
type ImageConfig struct {
|
||||
Image string `yaml:"image,omitempty"`
|
||||
}
|
||||
|
||||
func GetCacheImageList(cloudconfig string, oldcfg *config.CloudConfig) []string {
|
||||
savedImages := make([]string, 0)
|
||||
bytes, err := readConfigFile(cloudconfig)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Fatal("Failed to read cloud-config")
|
||||
return savedImages
|
||||
}
|
||||
r := make(map[interface{}]interface{})
|
||||
if err := yaml.Unmarshal(bytes, &r); err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Fatal("Failed to unmarshal cloud-config")
|
||||
return savedImages
|
||||
}
|
||||
newcfg := &config.CloudConfig{}
|
||||
if err := util.Convert(r, newcfg); err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Fatal("Failed to convert cloud-config")
|
||||
return savedImages
|
||||
}
|
||||
|
||||
// services_include
|
||||
for key, value := range newcfg.Rancher.ServicesInclude {
|
||||
if value {
|
||||
serviceImage := getServiceImage(key, "", oldcfg, newcfg)
|
||||
if serviceImage != "" {
|
||||
savedImages = append(savedImages, serviceImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// console
|
||||
newConsole := newcfg.Rancher.Console
|
||||
if newConsole != "" && newConsole != "default" {
|
||||
consoleImage := getServiceImage(newConsole, "console", oldcfg, newcfg)
|
||||
if consoleImage != "" {
|
||||
savedImages = append(savedImages, consoleImage)
|
||||
}
|
||||
}
|
||||
|
||||
// docker engine
|
||||
newEngine := newcfg.Rancher.Docker.Engine
|
||||
if newEngine != "" && newEngine != oldcfg.Rancher.Docker.Engine {
|
||||
engineImage := getServiceImage(newEngine, "docker", oldcfg, newcfg)
|
||||
if engineImage != "" {
|
||||
savedImages = append(savedImages, engineImage)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return savedImages
|
||||
}
|
||||
|
||||
func getServiceImage(service, svctype string, oldcfg, newcfg *config.CloudConfig) string {
|
||||
var (
|
||||
serviceImage string
|
||||
bytes []byte
|
||||
err error
|
||||
)
|
||||
if len(newcfg.Rancher.Repositories.ToArray()) > 0 {
|
||||
bytes, err = network.LoadServiceResource(service, true, newcfg)
|
||||
} else {
|
||||
bytes, err = network.LoadServiceResource(service, true, oldcfg)
|
||||
}
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Fatal("Failed to load service resource")
|
||||
return serviceImage
|
||||
}
|
||||
imageConfig := map[interface{}]ImageConfig{}
|
||||
if err = yaml.Unmarshal(bytes, &imageConfig); err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Fatal("Failed to unmarshal service")
|
||||
return serviceImage
|
||||
}
|
||||
switch svctype {
|
||||
case "console":
|
||||
serviceImage = formatImage(imageConfig["console"].Image, oldcfg, newcfg)
|
||||
case "docker":
|
||||
serviceImage = formatImage(imageConfig["docker"].Image, oldcfg, newcfg)
|
||||
default:
|
||||
serviceImage = formatImage(imageConfig[service].Image, oldcfg, newcfg)
|
||||
}
|
||||
|
||||
return serviceImage
|
||||
}
|
||||
|
||||
func RunCacheScript(partition string, images []string) error {
|
||||
return util.RunScript("/scripts/cache-services.sh", partition, strings.Join(images, " "))
|
||||
}
|
||||
|
||||
func readConfigFile(file string) ([]byte, error) {
|
||||
content, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
err = nil
|
||||
content = []byte{}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return content, err
|
||||
}
|
||||
|
||||
func formatImage(image string, oldcfg, newcfg *config.CloudConfig) string {
|
||||
registryDomain := newcfg.Rancher.Environment["REGISTRY_DOMAIN"]
|
||||
if registryDomain == "" {
|
||||
registryDomain = oldcfg.Rancher.Environment["REGISTRY_DOMAIN"]
|
||||
}
|
||||
image = strings.Replace(image, "${REGISTRY_DOMAIN}", registryDomain, -1)
|
||||
|
||||
image = strings.Replace(image, "${SUFFIX}", config.Suffix, -1)
|
||||
|
||||
return image
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
func syslinuxConfig(menu BootVars) error {
|
||||
|
||||
@@ -8,20 +8,21 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/cmd/power"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/compose"
|
||||
"github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/pkg/util/network"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
"github.com/rancher/os/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
dockerClient "github.com/docker/engine-api/client"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/project/options"
|
||||
"golang.org/x/net/context"
|
||||
"github.com/rancher/os/cmd/power"
|
||||
"github.com/rancher/os/compose"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/util"
|
||||
"github.com/rancher/os/util/network"
|
||||
)
|
||||
|
||||
type Images struct {
|
||||
@@ -71,14 +72,8 @@ func osSubcommands() []cli.Command {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "list",
|
||||
Usage: "list the current available versions",
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "update, u",
|
||||
Usage: "update engine cache",
|
||||
},
|
||||
},
|
||||
Name: "list",
|
||||
Usage: "list the current available versions",
|
||||
Action: osMetaDataGet,
|
||||
},
|
||||
{
|
||||
@@ -89,7 +84,7 @@ func osSubcommands() []cli.Command {
|
||||
}
|
||||
}
|
||||
|
||||
func getImages(update bool) (*Images, error) {
|
||||
func getImages() (*Images, error) {
|
||||
upgradeURL, err := getUpgradeURL()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -116,13 +111,6 @@ func getImages(update bool) (*Images, error) {
|
||||
u.RawQuery = q.Encode()
|
||||
upgradeURL = u.String()
|
||||
|
||||
if update {
|
||||
_, err := network.UpdateCache(upgradeURL)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to update os caches: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
body, err = network.LoadFromNetwork(upgradeURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -144,7 +132,7 @@ func getImages(update bool) (*Images, error) {
|
||||
}
|
||||
|
||||
func osMetaDataGet(c *cli.Context) error {
|
||||
images, err := getImages(c.Bool("update"))
|
||||
images, err := getImages()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -185,7 +173,7 @@ func osMetaDataGet(c *cli.Context) error {
|
||||
}
|
||||
|
||||
func getLatestImage() (string, error) {
|
||||
images, err := getImages(false)
|
||||
images, err := getImages()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -198,10 +186,6 @@ func osUpgrade(c *cli.Context) error {
|
||||
log.Fatalf("ros install / upgrade only supported on 'amd64', not '%s'", runtime.GOARCH)
|
||||
}
|
||||
|
||||
if isExist := checkGlobalCfg(); !isExist {
|
||||
log.Fatalf("ros upgrade cannot be supported")
|
||||
}
|
||||
|
||||
image := c.String("image")
|
||||
|
||||
if image == "" {
|
||||
|
||||
@@ -11,13 +11,13 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
|
||||
dockerClient "github.com/docker/engine-api/client"
|
||||
"github.com/docker/engine-api/types"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -54,20 +54,6 @@ func PreloadImages(clientFactory func() (dockerClient.APIClient, error), imagesD
|
||||
return err
|
||||
}
|
||||
|
||||
// try to load predefined user images
|
||||
if imagesDir == userImagesPreloadDirectory {
|
||||
oldUserImgName := path.Join(config.ImagesPath, config.UserImages)
|
||||
userImgfile, err := os.Stat(oldUserImgName)
|
||||
if err == nil {
|
||||
newUserImgName := path.Join(userImagesPreloadDirectory, userImgfile.Name())
|
||||
if _, err = os.Stat(newUserImgName); os.IsNotExist(err) {
|
||||
if err := os.Symlink(oldUserImgName, newUserImgName); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(imagesDir)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -5,9 +5,8 @@ import (
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
func recoveryInitAction(c *cli.Context) error {
|
||||
|
||||
@@ -4,14 +4,12 @@ import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/config"
|
||||
)
|
||||
|
||||
func selinuxCommand() cli.Command {
|
||||
app := cli.Command{}
|
||||
app.Hidden = true
|
||||
app.Name = "selinux"
|
||||
app.Action = func(c *cli.Context) error {
|
||||
argv := []string{"system-docker", "run", "-it", "--privileged", "--rm",
|
||||
|
||||
@@ -7,12 +7,12 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/log"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/docker/libcompose/project/options"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func ProjectPs(p project.APIProject, c *cli.Context) error {
|
||||
@@ -85,7 +85,6 @@ func ProjectUp(p project.APIProject, c *cli.Context) error {
|
||||
if err != nil {
|
||||
return cli.NewExitError(err.Error(), 1)
|
||||
}
|
||||
|
||||
if c.Bool("foreground") {
|
||||
signalChan := make(chan os.Signal, 1)
|
||||
cleanupDone := make(chan bool)
|
||||
|
||||
@@ -3,10 +3,9 @@ package command
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/rancher/os/cmd/control/service/app"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
composeApp "github.com/docker/libcompose/cli/app"
|
||||
"github.com/rancher/os/cmd/control/service/app"
|
||||
)
|
||||
|
||||
func verifyOneOrMoreServices(c *cli.Context) error {
|
||||
|
||||
@@ -4,16 +4,15 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/cmd/control/service/command"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/compose"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/pkg/util/network"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
dockerApp "github.com/docker/libcompose/cli/docker/app"
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/rancher/os/cmd/control/service/command"
|
||||
"github.com/rancher/os/compose"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
"github.com/rancher/os/util/network"
|
||||
)
|
||||
|
||||
type projectFactory struct {
|
||||
@@ -71,18 +70,8 @@ func serviceSubCommands() []cli.Command {
|
||||
Action: disable,
|
||||
},
|
||||
{
|
||||
Name: "list",
|
||||
Usage: "list services and state",
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "all, a",
|
||||
Usage: "list all services and state",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "update, u",
|
||||
Usage: "update service cache",
|
||||
},
|
||||
},
|
||||
Name: "list",
|
||||
Usage: "list services and state",
|
||||
Action: list,
|
||||
},
|
||||
{
|
||||
@@ -184,13 +173,7 @@ func list(c *cli.Context) error {
|
||||
clone[service] = enabled
|
||||
}
|
||||
|
||||
services := availableService(cfg, c.Bool("update"))
|
||||
|
||||
if c.Bool("all") {
|
||||
for service := range cfg.Rancher.Services {
|
||||
fmt.Printf("enabled %s\n", service)
|
||||
}
|
||||
}
|
||||
services := availableService(cfg)
|
||||
|
||||
for _, service := range services {
|
||||
if enabled, ok := clone[service]; ok {
|
||||
@@ -226,7 +209,7 @@ func IsLocalOrURL(service string) bool {
|
||||
|
||||
// ValidService checks to see if the service definition exists
|
||||
func ValidService(service string, cfg *config.CloudConfig) bool {
|
||||
services := availableService(cfg, false)
|
||||
services := availableService(cfg)
|
||||
if !IsLocalOrURL(service) && !util.Contains(services, service) {
|
||||
return false
|
||||
}
|
||||
@@ -239,14 +222,7 @@ func validateService(service string, cfg *config.CloudConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
func availableService(cfg *config.CloudConfig, update bool) []string {
|
||||
if update {
|
||||
err := network.UpdateCaches(cfg.Rancher.Repositories.ToArray(), "services")
|
||||
if err != nil {
|
||||
log.Debugf("Failed to update service caches: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
func availableService(cfg *config.CloudConfig) []string {
|
||||
services, err := network.GetServices(cfg.Rancher.Repositories.ToArray())
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to get services: %v", err)
|
||||
|
||||
@@ -3,12 +3,11 @@ package control
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/compose"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/docker/libcompose/project/options"
|
||||
"github.com/rancher/os/compose"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/log"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
@@ -25,14 +24,6 @@ func switchConsoleAction(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// stop docker and console to avoid zombie process
|
||||
if err = project.Stop(context.Background(), 10, "docker"); err != nil {
|
||||
log.Errorf("Failed to stop Docker: %v", err)
|
||||
}
|
||||
if err = project.Stop(context.Background(), 10, "console"); err != nil {
|
||||
log.Errorf("Failed to stop console: %v", err)
|
||||
}
|
||||
|
||||
if newConsole != "default" {
|
||||
if err = compose.LoadSpecialService(project, cfg, "console", newConsole); err != nil {
|
||||
return err
|
||||
@@ -49,8 +40,8 @@ func switchConsoleAction(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = project.Start(context.Background(), "docker"); err != nil {
|
||||
log.Errorf("Failed to start Docker: %v", err)
|
||||
if err = project.Restart(context.Background(), 10, "docker"); err != nil {
|
||||
log.Errorf("Failed to restart Docker: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -5,12 +5,12 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
machineUtil "github.com/docker/machine/utils"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,64 +1,21 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
func udevSettleAction(c *cli.Context) {
|
||||
if err := extraRules(); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
if err := UdevSettle(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func extraRules() error {
|
||||
cfg := config.LoadConfig()
|
||||
if len(cfg.Rancher.Network.ModemNetworks) > 0 {
|
||||
rules, err := ioutil.ReadDir(config.UdevRulesExtrasDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, r := range rules {
|
||||
if r.IsDir() || filepath.Ext(r.Name()) != ".rules" {
|
||||
continue
|
||||
}
|
||||
err := os.Symlink(filepath.Join(config.UdevRulesExtrasDir, r.Name()), filepath.Join(config.UdevRulesDir, r.Name()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rules, err := ioutil.ReadDir(config.UdevRulesDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, r := range rules {
|
||||
if r.IsDir() || (filepath.Ext(r.Name()) != ".rules") || (r.Mode()&os.ModeSymlink != 0) {
|
||||
continue
|
||||
}
|
||||
err := os.Remove(filepath.Join(config.UdevRulesDir, r.Name()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func UdevSettle() error {
|
||||
cmd := exec.Command("udevd", "--daemon")
|
||||
defer exec.Command("killall", "udevd").Run()
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
|
||||
@@ -5,20 +5,21 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/compose"
|
||||
rosDocker "github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"path/filepath"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
composeClient "github.com/docker/libcompose/docker/client"
|
||||
"github.com/docker/libcompose/project"
|
||||
"golang.org/x/net/context"
|
||||
"github.com/rancher/os/compose"
|
||||
"github.com/rancher/os/config"
|
||||
rosDocker "github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -26,7 +27,6 @@ const (
|
||||
dockerPidFile = "/var/run/docker.pid"
|
||||
sourceDirectory = "/engine"
|
||||
destDirectory = "/var/lib/rancher/engine"
|
||||
dockerCompletionFName = "completion"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -95,14 +95,8 @@ func copyBinaries(source, dest string) error {
|
||||
if err = out.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
if file.Name() == dockerCompletionFName {
|
||||
if err := os.Chmod(destFile, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := os.Chmod(destFile, 0751); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Chmod(destFile, 0751); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,15 +3,11 @@ package control
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
func yes(question string) bool {
|
||||
@@ -32,55 +28,3 @@ func formatImage(image string, cfg *config.CloudConfig) string {
|
||||
}
|
||||
return image
|
||||
}
|
||||
|
||||
func symLinkEngineBinary() []symlink {
|
||||
baseSymlink := []symlink{
|
||||
{"/usr/share/ros/os-release", "/usr/lib/os-release"},
|
||||
{"/usr/share/ros/os-release", "/etc/os-release"},
|
||||
|
||||
{"/var/lib/rancher/engine/docker", "/usr/bin/docker"},
|
||||
{"/var/lib/rancher/engine/dockerd", "/usr/bin/dockerd"},
|
||||
{"/var/lib/rancher/engine/docker-init", "/usr/bin/docker-init"},
|
||||
{"/var/lib/rancher/engine/docker-proxy", "/usr/bin/docker-proxy"},
|
||||
|
||||
// >= 18.09.0
|
||||
{"/var/lib/rancher/engine/containerd", "/usr/bin/containerd"},
|
||||
{"/var/lib/rancher/engine/ctr", "/usr/bin/ctr"},
|
||||
{"/var/lib/rancher/engine/containerd-shim", "/usr/bin/containerd-shim"},
|
||||
{"/var/lib/rancher/engine/runc", "/usr/bin/runc"},
|
||||
|
||||
// < 18.09.0
|
||||
{"/var/lib/rancher/engine/docker-containerd", "/usr/bin/docker-containerd"},
|
||||
{"/var/lib/rancher/engine/docker-containerd-ctr", "/usr/bin/docker-containerd-ctr"},
|
||||
{"/var/lib/rancher/engine/docker-containerd-shim", "/usr/bin/docker-containerd-shim"},
|
||||
{"/var/lib/rancher/engine/docker-runc", "/usr/bin/docker-runc"},
|
||||
}
|
||||
return baseSymlink
|
||||
}
|
||||
|
||||
func checkZfsBackingFS(driver, dir string) error {
|
||||
if driver != "zfs" {
|
||||
return nil
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
mountInfo, err := ioutil.ReadFile("/proc/self/mountinfo")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, mount := range strings.Split(string(mountInfo), "\n") {
|
||||
if strings.Contains(mount, dir) && strings.Contains(mount, driver) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
return errors.Errorf("BackingFS: %s not match storage-driver: %s", dir, driver)
|
||||
}
|
||||
|
||||
func checkGlobalCfg() bool {
|
||||
_, err := os.Stat("/proc/1/root/boot/global.cfg")
|
||||
if err == nil || os.IsExist(err) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
// +build linux
|
||||
|
||||
package init
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/dfs"
|
||||
"github.com/rancher/os/pkg/init/b2d"
|
||||
"github.com/rancher/os/pkg/init/cloudinit"
|
||||
"github.com/rancher/os/pkg/init/configfiles"
|
||||
"github.com/rancher/os/pkg/init/debug"
|
||||
"github.com/rancher/os/pkg/init/docker"
|
||||
"github.com/rancher/os/pkg/init/env"
|
||||
"github.com/rancher/os/pkg/init/fsmount"
|
||||
"github.com/rancher/os/pkg/init/hypervisor"
|
||||
"github.com/rancher/os/pkg/init/modules"
|
||||
"github.com/rancher/os/pkg/init/one"
|
||||
"github.com/rancher/os/pkg/init/prepare"
|
||||
"github.com/rancher/os/pkg/init/recovery"
|
||||
"github.com/rancher/os/pkg/init/selinux"
|
||||
"github.com/rancher/os/pkg/init/sharedroot"
|
||||
"github.com/rancher/os/pkg/init/switchroot"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/sysinit"
|
||||
)
|
||||
|
||||
func MainInit() {
|
||||
log.InitLogger()
|
||||
// TODO: this breaks and does nothing if the cfg is invalid (or is it due to threading?)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Printf("Starting Recovery console: %v\n", r)
|
||||
recovery.Recovery(nil)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := RunInit(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func RunInit() error {
|
||||
initFuncs := config.CfgFuncs{
|
||||
{"set env", env.Init},
|
||||
{"preparefs", prepare.FS},
|
||||
{"save init cmdline", prepare.SaveCmdline},
|
||||
{"mount OEM", fsmount.MountOem},
|
||||
{"debug save cfg", debug.PrintAndLoadConfig},
|
||||
{"load modules", modules.LoadModules},
|
||||
{"recovery console", recovery.LoadRecoveryConsole},
|
||||
{"b2d env", b2d.B2D},
|
||||
{"mount STATE and bootstrap", fsmount.MountStateAndBootstrap},
|
||||
{"cloud-init", cloudinit.CloudInit},
|
||||
{"read cfg and log files", configfiles.ReadConfigFiles},
|
||||
{"switchroot", switchroot.SwitchRoot},
|
||||
{"mount OEM2", fsmount.MountOem},
|
||||
{"mount BOOT", fsmount.MountBoot},
|
||||
{"write cfg and log files", configfiles.WriteConfigFiles},
|
||||
{"b2d Env", b2d.Env},
|
||||
{"hypervisor tools", hypervisor.Tools},
|
||||
{"preparefs2", prepare.FS},
|
||||
{"load modules2", modules.LoadModules},
|
||||
{"set proxy env", env.Proxy},
|
||||
{"init SELinux", selinux.Initialize},
|
||||
{"setupSharedRoot", sharedroot.Setup},
|
||||
{"sysinit", sysinit.RunSysInit},
|
||||
}
|
||||
|
||||
cfg, err := config.ChainCfgFuncs(nil, initFuncs)
|
||||
if err != nil {
|
||||
recovery.Recovery(err)
|
||||
}
|
||||
|
||||
launchConfig, args := docker.GetLaunchConfig(cfg, &cfg.Rancher.SystemDocker)
|
||||
launchConfig.Fork = !cfg.Rancher.SystemDocker.Exec
|
||||
//launchConfig.NoLog = true
|
||||
|
||||
log.Info("Launching System Docker")
|
||||
_, err = dfs.LaunchDocker(launchConfig, config.SystemDockerBin, args...)
|
||||
if err != nil {
|
||||
log.Errorf("Error Launching System Docker: %s", err)
|
||||
recovery.Recovery(err)
|
||||
return err
|
||||
}
|
||||
// Code never gets here - rancher.system_docker.exec=true
|
||||
|
||||
return one.PidOne()
|
||||
}
|
||||
@@ -1,31 +1,19 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"text/template"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/hostname"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/log"
|
||||
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/docker/libnetwork/resolvconf"
|
||||
"golang.org/x/net/context"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/hostname"
|
||||
"github.com/rancher/os/netconf"
|
||||
)
|
||||
|
||||
var funcMap = template.FuncMap{
|
||||
"addFunc": func(a, b int) string {
|
||||
return strconv.Itoa(a + b)
|
||||
},
|
||||
}
|
||||
|
||||
func Main() {
|
||||
log.InitLogger()
|
||||
|
||||
@@ -42,12 +30,7 @@ func Main() {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
signalChan := make(chan os.Signal, 1)
|
||||
signal.Notify(signalChan, syscall.SIGTERM)
|
||||
<-signalChan
|
||||
log.Info("Received SIGTERM, shutting down")
|
||||
netconf.StopWpaSupplicant()
|
||||
netconf.StopDhcpcd()
|
||||
select {}
|
||||
}
|
||||
|
||||
func ApplyNetworkConfig(cfg *config.CloudConfig) {
|
||||
@@ -59,17 +42,6 @@ func ApplyNetworkConfig(cfg *config.CloudConfig) {
|
||||
}
|
||||
|
||||
userSetHostname := cfg.Hostname != ""
|
||||
if cfg.Rancher.Network.DHCPTimeout <= 0 {
|
||||
cfg.Rancher.Network.DHCPTimeout = cfg.Rancher.Defaults.Network.DHCPTimeout
|
||||
}
|
||||
|
||||
// In order to handle the STATIC mode in Wi-Fi network, we have to update the dhcpcd.conf file.
|
||||
// https://wiki.archlinux.org/index.php/dhcpcd#Static_profile
|
||||
if len(cfg.Rancher.Network.WifiNetworks) > 0 {
|
||||
generateDhcpcdFiles(cfg)
|
||||
generateWpaFiles(cfg)
|
||||
}
|
||||
|
||||
dhcpSetDNS, err := netconf.ApplyNetworkConfigs(&cfg.Rancher.Network, userSetHostname, userSetDNS)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to apply network configs(by netconf): %v", err)
|
||||
@@ -105,50 +77,3 @@ func ApplyNetworkConfig(cfg *config.CloudConfig) {
|
||||
log.Errorf("Failed to sync hostname: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func generateDhcpcdFiles(cfg *config.CloudConfig) {
|
||||
networks := cfg.Rancher.Network.WifiNetworks
|
||||
interfaces := cfg.Rancher.Network.Interfaces
|
||||
configs := make(map[string]netconf.WifiNetworkConfig)
|
||||
for k, v := range interfaces {
|
||||
if c, ok := networks[v.WifiNetwork]; ok && c.Address != "" {
|
||||
configs[k] = c
|
||||
}
|
||||
}
|
||||
f, err := os.Create(config.DHCPCDConfigFile)
|
||||
defer f.Close()
|
||||
if err != nil {
|
||||
log.Errorf("Failed to open file: %s err: %v", config.DHCPCDConfigFile, err)
|
||||
}
|
||||
templateFiles := []string{config.DHCPCDTemplateFile}
|
||||
templateName := filepath.Base(templateFiles[0])
|
||||
p := template.Must(template.New(templateName).ParseFiles(templateFiles...))
|
||||
if err = p.Execute(f, configs); err != nil {
|
||||
log.Errorf("Failed to wrote wpa configuration to %s: %v", config.DHCPCDConfigFile, err)
|
||||
}
|
||||
}
|
||||
|
||||
func generateWpaFiles(cfg *config.CloudConfig) {
|
||||
networks := cfg.Rancher.Network.WifiNetworks
|
||||
interfaces := cfg.Rancher.Network.Interfaces
|
||||
for k, v := range interfaces {
|
||||
if v.WifiNetwork != "" {
|
||||
configs := make(map[string]netconf.WifiNetworkConfig)
|
||||
filename := fmt.Sprintf(config.WPAConfigFile, k)
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to open file: %s err: %v", filename, err)
|
||||
}
|
||||
if c, ok := networks[v.WifiNetwork]; ok {
|
||||
configs[v.WifiNetwork] = c
|
||||
}
|
||||
templateFiles := []string{config.WPATemplateFile}
|
||||
templateName := filepath.Base(templateFiles[0])
|
||||
p := template.Must(template.New(templateName).Funcs(funcMap).ParseFiles(templateFiles...))
|
||||
if err = p.Execute(f, configs); err != nil {
|
||||
log.Errorf("Failed to wrote wpa configuration to %s: %v", filename, err)
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,16 +10,17 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/os/cmd/control/install"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/docker/engine-api/types"
|
||||
"github.com/docker/engine-api/types/container"
|
||||
"github.com/docker/engine-api/types/filters"
|
||||
"golang.org/x/net/context"
|
||||
"github.com/rancher/os/cmd/control/install"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/log"
|
||||
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
// You can't shutdown the system from a process in console because we want to stop the console container.
|
||||
@@ -48,7 +49,6 @@ func runDocker(name string) error {
|
||||
|
||||
existing, err := client.ContainerInspect(context.Background(), containerName)
|
||||
if err == nil && existing.ID != "" {
|
||||
// remove the old version of reboot
|
||||
err := client.ContainerRemove(context.Background(), types.ContainerRemoveOptions{
|
||||
ContainerID: existing.ID,
|
||||
})
|
||||
@@ -77,8 +77,7 @@ func runDocker(name string) error {
|
||||
},
|
||||
},
|
||||
&container.HostConfig{
|
||||
PidMode: "host",
|
||||
NetworkMode: "none",
|
||||
PidMode: "host",
|
||||
VolumesFrom: []string{
|
||||
currentContainer.ID,
|
||||
},
|
||||
@@ -131,23 +130,8 @@ func reboot(name string, force bool, code uint) {
|
||||
log.Fatalf("%s: Need to be root", os.Args[0])
|
||||
}
|
||||
|
||||
cfg := config.LoadConfig()
|
||||
|
||||
// Validate config
|
||||
if !force {
|
||||
_, validationErrors, err := config.LoadConfigWithError()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if validationErrors != nil && !validationErrors.Valid() {
|
||||
for _, validationError := range validationErrors.Errors() {
|
||||
log.Error(validationError)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Add shutdown timeout
|
||||
cfg := config.LoadConfig()
|
||||
timeoutValue := cfg.Rancher.ShutdownTimeout
|
||||
if timeoutValue == 0 {
|
||||
timeoutValue = 60
|
||||
@@ -194,7 +178,7 @@ func reboot(name string, force bool, code uint) {
|
||||
return
|
||||
}
|
||||
defer util.Unmount(baseName)
|
||||
Kexec(previouskexecFlag, filepath.Join(baseName, config.BootDir), kexecAppendFlag)
|
||||
Kexec(previouskexecFlag, filepath.Join(baseName, install.BootDir), kexecAppendFlag)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -7,11 +7,10 @@ import (
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/cmd/control/install"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -13,10 +13,9 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -137,14 +136,19 @@ func execute(line string, doneChannel chan string) {
|
||||
Setsid: true,
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err == nil {
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
log.Errorf("%s : %v", line, err)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
addProcess(cmd.Process)
|
||||
if err = cmd.Wait(); err != nil {
|
||||
log.Errorf("Wait cmd to exit: %s, err: %v", line, err)
|
||||
}
|
||||
err = cmd.Wait()
|
||||
removeProcess(cmd.Process)
|
||||
} else {
|
||||
log.Errorf("Start cmd: %s, err: %v", line, err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("%s : %v", line, err)
|
||||
}
|
||||
|
||||
if !running {
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/sysinit"
|
||||
initPkg "github.com/rancher/os/init"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
func Main() {
|
||||
@@ -15,7 +15,7 @@ func Main() {
|
||||
log.Infof("Resolv.conf == [%s], %v", resolve, err)
|
||||
log.Infof("Exec %v", os.Args)
|
||||
|
||||
if err := sysinit.SysInit(); err != nil {
|
||||
if err := initPkg.SysInit(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
func Main() {
|
||||
|
||||
@@ -2,14 +2,8 @@ package compose
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
rosDocker "github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/pkg/util/network"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
dockerClient "github.com/docker/engine-api/client"
|
||||
@@ -17,10 +11,15 @@ import (
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/docker"
|
||||
composeClient "github.com/docker/libcompose/docker/client"
|
||||
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/docker/libcompose/project/events"
|
||||
"github.com/docker/libcompose/project/options"
|
||||
"golang.org/x/net/context"
|
||||
"github.com/rancher/os/config"
|
||||
rosDocker "github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
"github.com/rancher/os/util/network"
|
||||
)
|
||||
|
||||
func CreateService(cfg *config.CloudConfig, name string, serviceConfig *composeConfig.ServiceConfigV1) (project.Service, error) {
|
||||
@@ -225,31 +224,8 @@ func StageServices(cfg *config.CloudConfig, services ...string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// read engine services
|
||||
composeConfigs := map[string]composeConfig.ServiceConfigV1{}
|
||||
if _, err := os.Stat(config.MultiDockerConfFile); err == nil {
|
||||
// read from engine compose
|
||||
multiEngineBytes, err := ioutil.ReadFile(config.MultiDockerConfFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to read %s : %v", config.MultiDockerConfFile, err)
|
||||
}
|
||||
err = yaml.Unmarshal(multiEngineBytes, &composeConfigs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to unmarshal %s : %v", config.MultiDockerConfFile, err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, service := range services {
|
||||
var bytes []byte
|
||||
foundServiceConfig := map[string]composeConfig.ServiceConfigV1{}
|
||||
|
||||
if _, ok := composeConfigs[service]; ok {
|
||||
foundServiceConfig[service] = composeConfigs[service]
|
||||
bytes, err = yaml.Marshal(foundServiceConfig)
|
||||
} else {
|
||||
bytes, err = network.LoadServiceResource(service, true, cfg)
|
||||
}
|
||||
|
||||
bytes, err := network.LoadServiceResource(service, true, cfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to load %s : %v", service, err)
|
||||
}
|
||||
@@ -3,27 +3,20 @@ package compose
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/docker"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util/network"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util/network"
|
||||
)
|
||||
|
||||
func LoadService(p *project.Project, cfg *config.CloudConfig, useNetwork bool, service string) error {
|
||||
// First check the multi engine service file.
|
||||
// If the name has been found in multi enging service file and matches, will not execute network.LoadServiceResource
|
||||
// Otherwise will execute network.LoadServiceResource
|
||||
bytes, err := network.LoadMultiEngineResource(service)
|
||||
if err != nil || bytes == nil {
|
||||
bytes, err = network.LoadServiceResource(service, useNetwork, cfg)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
bytes, err := network.LoadServiceResource(service, useNetwork, cfg)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
m := map[interface{}]interface{}{}
|
||||
@@ -36,6 +36,5 @@ image and use a plain directory containing the same contents:
|
||||
qemu-system-x86_64 \
|
||||
-fsdev local,id=conf,security_model=none,readonly,path=/tmp/new-drive \
|
||||
-device virtio-9p-pci,fsdev=conf,mount_tag=config-2 \
|
||||
-device virtio-rng-pci \
|
||||
[usual qemu options here...]
|
||||
```
|
||||
|
||||
@@ -149,7 +149,7 @@ func coerceNodes(w, s Node) Node {
|
||||
return n
|
||||
}
|
||||
|
||||
// normalizeNodeNames replaces all occurrences of '-' with '_' within key names
|
||||
// normalizeNodeNames replaces all occurences of '-' with '_' within key names
|
||||
// and makes a note of each replacement in the report.
|
||||
func normalizeNodeNames(node Node, report *Report) Node {
|
||||
if strings.Contains(node.name, "-") {
|
||||
|
||||
@@ -22,6 +22,6 @@ COVERPKG=${COVERPKG//./}
|
||||
# generate arg for "go test"
|
||||
export COVER="-coverprofile ${COVEROUT}/${COVERPKG}.out"
|
||||
|
||||
source test
|
||||
source ./test
|
||||
|
||||
go tool cover -html=${COVEROUT}/${COVERPKG}.out
|
||||
|
||||
@@ -22,11 +22,11 @@ import (
|
||||
"path"
|
||||
"syscall"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/log"
|
||||
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -70,7 +70,7 @@ func (cd *ConfigDrive) Finish() error {
|
||||
|
||||
func (cd *ConfigDrive) String() string {
|
||||
if cd.lastError != nil {
|
||||
return fmt.Sprintf("%s: %s (lastError: %v)", cd.Type(), cd.root, cd.lastError)
|
||||
return fmt.Sprintf("%s: %s (lastError: %s)", cd.Type(), cd.root, cd.lastError)
|
||||
}
|
||||
return fmt.Sprintf("%s: %s", cd.Type(), cd.root)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ package datasource
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
"github.com/rancher/os/netconf"
|
||||
)
|
||||
|
||||
type Datasource interface {
|
||||
@@ -28,7 +28,7 @@ type Datasource interface {
|
||||
FetchUserdata() ([]byte, error)
|
||||
Type() string
|
||||
String() string
|
||||
// Finish gives the datasource the opportunity to clean up, unmount or release any open / cache resources
|
||||
// Finish gives the datasource the oportunity to clean up, unmount or release any open / cache resources
|
||||
Finish() error
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ func (f *LocalFile) Finish() error {
|
||||
}
|
||||
|
||||
func (f *LocalFile) String() string {
|
||||
return fmt.Sprintf("%s: %s (lastError: %v)", f.Type(), f.path, f.lastError)
|
||||
return fmt.Sprintf("%s: %s (lastError: %s)", f.Type(), f.path, f.lastError)
|
||||
}
|
||||
|
||||
func (f *LocalFile) AvailabilityChanges() bool {
|
||||
|
||||
@@ -5,9 +5,10 @@ import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/netconf"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/config"
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
)
|
||||
|
||||
const (
|
||||
metadataHeader = "true"
|
||||
metadataVersion = "2019-02-01"
|
||||
metadataEndpoint = "http://169.254.169.254/metadata/"
|
||||
)
|
||||
|
||||
type MetadataService struct {
|
||||
metadata.Service
|
||||
}
|
||||
|
||||
func NewDatasource(root string) *MetadataService {
|
||||
if root == "" {
|
||||
root = metadataEndpoint
|
||||
}
|
||||
return &MetadataService{metadata.NewDatasource(root, "instance?api-version="+metadataVersion+"&format=json", "", "", assembleHeader())}
|
||||
}
|
||||
|
||||
func (ms MetadataService) ConfigRoot() string {
|
||||
return ms.Root + "instance"
|
||||
}
|
||||
|
||||
func (ms MetadataService) AvailabilityChanges() bool {
|
||||
// TODO: if it can't find the network, maybe we can start it?
|
||||
return false
|
||||
}
|
||||
|
||||
func (ms MetadataService) FetchMetadata() (datasource.Metadata, error) {
|
||||
d, err := ms.FetchData(ms.MetadataURL())
|
||||
if err != nil {
|
||||
return datasource.Metadata{}, err
|
||||
}
|
||||
type Plan struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Product string `json:"product,omitempty"`
|
||||
Publisher string `json:"publisher,omitempty"`
|
||||
}
|
||||
type PublicKey struct {
|
||||
KeyData string `json:"keyData,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
}
|
||||
type Compute struct {
|
||||
AZEnvironment string `json:"azEnvironment,omitempty"`
|
||||
CustomData string `json:"customData,omitempty"`
|
||||
Location string `json:"location,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Offer string `json:"offer,omitempty"`
|
||||
OSType string `json:"osType,omitempty"`
|
||||
PlacementGroupID string `json:"placementGroupId,omitempty"`
|
||||
Plan Plan `json:"plan,omitempty"`
|
||||
PlatformFaultDomain string `json:"platformFaultDomain,omitempty"`
|
||||
PlatformUpdateDomain string `json:"platformUpdateDomain,omitempty"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
PublicKeys []PublicKey `json:"publicKeys,omitempty"`
|
||||
Publisher string `json:"publisher,omitempty"`
|
||||
ResourceGroupName string `json:"resourceGroupName,omitempty"`
|
||||
SKU string `json:"sku,omitempty"`
|
||||
SubscriptionID string `json:"subscriptionId,omitempty"`
|
||||
Tags string `json:"tags,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
VMID string `json:"vmId,omitempty"`
|
||||
VMScaleSetName string `json:"vmScaleSetName,omitempty"`
|
||||
VMSize string `json:"vmSize,omitempty"`
|
||||
Zone string `json:"zone,omitempty"`
|
||||
}
|
||||
type IPAddress struct {
|
||||
PrivateIPAddress string `json:"privateIpAddress,omitempty"`
|
||||
PublicIPAddress string `json:"publicIpAddress,omitempty"`
|
||||
}
|
||||
type Subnet struct {
|
||||
Address string `json:"address,omitempty"`
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
}
|
||||
type IPV4 struct {
|
||||
IPAddress []IPAddress `json:"ipAddress,omitempty"`
|
||||
Subnet []Subnet `json:"subnet,omitempty"`
|
||||
}
|
||||
type IPV6 struct {
|
||||
IPAddress []IPAddress `json:"ipAddress,omitempty"`
|
||||
}
|
||||
type Interface struct {
|
||||
IPV4 IPV4 `json:"ipv4,omitempty"`
|
||||
IPV6 IPV6 `json:"ipv6,omitempty"`
|
||||
MacAddress string `json:"macAddress,omitempty"`
|
||||
}
|
||||
type Network struct {
|
||||
Interface []Interface `json:"interface,omitempty"`
|
||||
}
|
||||
type Instance struct {
|
||||
Compute Compute `json:"compute,omitempty"`
|
||||
Network Network `json:"network,omitempty"`
|
||||
}
|
||||
instance := &Instance{}
|
||||
if err := json.Unmarshal(d, instance); err != nil {
|
||||
return datasource.Metadata{}, err
|
||||
}
|
||||
m := datasource.Metadata{
|
||||
Hostname: instance.Compute.Name,
|
||||
SSHPublicKeys: make(map[string]string, 0),
|
||||
}
|
||||
if len(instance.Network.Interface) > 0 {
|
||||
if len(instance.Network.Interface[0].IPV4.IPAddress) > 0 {
|
||||
m.PublicIPv4 = net.ParseIP(instance.Network.Interface[0].IPV4.IPAddress[0].PublicIPAddress)
|
||||
m.PrivateIPv4 = net.ParseIP(instance.Network.Interface[0].IPV4.IPAddress[0].PrivateIPAddress)
|
||||
}
|
||||
if len(instance.Network.Interface[0].IPV6.IPAddress) > 0 {
|
||||
m.PublicIPv6 = net.ParseIP(instance.Network.Interface[0].IPV6.IPAddress[0].PublicIPAddress)
|
||||
m.PrivateIPv6 = net.ParseIP(instance.Network.Interface[0].IPV6.IPAddress[0].PrivateIPAddress)
|
||||
}
|
||||
}
|
||||
for i, k := range instance.Compute.PublicKeys {
|
||||
m.SSHPublicKeys[strconv.Itoa(i)] = k.KeyData
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (ms MetadataService) FetchUserdata() ([]byte, error) {
|
||||
d, err := ms.FetchData(ms.UserdataURL())
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return config.DecodeBase64Content(string(d))
|
||||
}
|
||||
|
||||
func (ms MetadataService) Type() string {
|
||||
return "azure-metadata-service"
|
||||
}
|
||||
|
||||
func (ms MetadataService) MetadataURL() string {
|
||||
// metadata: http://169.254.169.254/metadata/instance?api-version=2019-02-01&format=json
|
||||
return ms.Root + "instance?api-version=" + metadataVersion + "&format=json"
|
||||
}
|
||||
|
||||
func (ms MetadataService) UserdataURL() string {
|
||||
// userdata: http://169.254.169.254/metadata/instance/compute/customData?api-version=2019-02-01&format=text
|
||||
return ms.Root + "instance/compute/customData?api-version=" + metadataVersion + "&format=text"
|
||||
}
|
||||
|
||||
func assembleHeader() http.Header {
|
||||
h := http.Header{}
|
||||
h.Add("Metadata", metadataHeader)
|
||||
return h
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/test"
|
||||
)
|
||||
|
||||
func TestType(t *testing.T) {
|
||||
want := "azure-metadata-service"
|
||||
if kind := (MetadataService{}).Type(); kind != want {
|
||||
t.Fatalf("bad type: want %q, got %q", want, kind)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetadataURL(t *testing.T) {
|
||||
want := "http://169.254.169.254/metadata/instance?api-version=2019-02-01&format=json"
|
||||
ms := NewDatasource("")
|
||||
if url := ms.MetadataURL(); url != want {
|
||||
t.Fatalf("bad url: want %q, got %q", want, url)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserdataURL(t *testing.T) {
|
||||
want := "http://169.254.169.254/metadata/instance/compute/customData?api-version=2019-02-01&format=text"
|
||||
ms := NewDatasource("")
|
||||
if url := ms.UserdataURL(); url != want {
|
||||
t.Fatalf("bad url: want %q, got %q", want, url)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchMetadata(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
root string
|
||||
metadataPath string
|
||||
resources map[string]string
|
||||
expect datasource.Metadata
|
||||
clientErr error
|
||||
expectErr error
|
||||
}{
|
||||
{
|
||||
root: "/metadata/",
|
||||
resources: map[string]string{
|
||||
"/metadata/instance?api-version=2019-02-01&format=json": `{
|
||||
"compute": {
|
||||
"azEnvironment": "AZUREPUBLICCLOUD",
|
||||
"location": "westus",
|
||||
"name": "rancheros",
|
||||
"offer": "",
|
||||
"osType": "Linux",
|
||||
"placementGroupId": "",
|
||||
"plan": {
|
||||
"name": "",
|
||||
"product": "",
|
||||
"publisher": ""
|
||||
},
|
||||
"platformFaultDomain": "0",
|
||||
"platformUpdateDomain": "0",
|
||||
"provider": "Microsoft.Compute",
|
||||
"publicKeys": [{
|
||||
"keyData":"publickey1",
|
||||
"path": "/home/rancher/.ssh/authorized_keys"
|
||||
}],
|
||||
"publisher": "",
|
||||
"resourceGroupName": "rancheros",
|
||||
"sku": "Enterprise",
|
||||
"subscriptionId": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",
|
||||
"tags": "",
|
||||
"version": "",
|
||||
"vmId": "453945c8-3923-4366-b2d3-ea4c80e9b70e",
|
||||
"vmScaleSetName": "",
|
||||
"vmSize": "Standard_A1",
|
||||
"zone": ""
|
||||
},
|
||||
"network": {
|
||||
"interface": [{
|
||||
"ipv4": {
|
||||
"ipAddress": [{
|
||||
"privateIpAddress": "192.168.1.2",
|
||||
"publicIpAddress": "5.6.7.8"
|
||||
}],
|
||||
"subnet": [{
|
||||
"address": "192.168.1.0",
|
||||
"prefix": "24"
|
||||
}]
|
||||
},
|
||||
"ipv6": {
|
||||
"ipAddress": []
|
||||
},
|
||||
"macAddress": "002248020E1E"
|
||||
}]
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
expect: datasource.Metadata{
|
||||
PrivateIPv4: net.ParseIP("192.168.1.2"),
|
||||
PublicIPv4: net.ParseIP("5.6.7.8"),
|
||||
SSHPublicKeys: map[string]string{
|
||||
"0": "publickey1",
|
||||
},
|
||||
Hostname: "rancheros",
|
||||
},
|
||||
},
|
||||
} {
|
||||
service := &MetadataService{
|
||||
Service: metadata.Service{
|
||||
Root: tt.root,
|
||||
Client: &test.HTTPClient{Resources: tt.resources, Err: tt.clientErr},
|
||||
},
|
||||
}
|
||||
metadata, err := service.FetchMetadata()
|
||||
if Error(err) != Error(tt.expectErr) {
|
||||
t.Fatalf("bad error (%q): \nwant %#v,\n got %#v", tt.resources, tt.expectErr, err)
|
||||
}
|
||||
if !reflect.DeepEqual(tt.expect, metadata) {
|
||||
t.Fatalf("bad fetch (%q): \nwant %#v,\n got %#v", tt.resources, tt.expect, metadata)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchUserdata(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
root string
|
||||
userdataPath string
|
||||
resources map[string]string
|
||||
userdata []byte
|
||||
clientErr error
|
||||
expectErr error
|
||||
}{
|
||||
{
|
||||
root: "/metadata/",
|
||||
resources: map[string]string{
|
||||
"/metadata/instance/compute/customData?api-version=2019-02-01&format=text": "I2Nsb3VkLWNvbmZpZwpob3N0bmFtZTogcmFuY2hlcjE=",
|
||||
},
|
||||
userdata: []byte(`#cloud-config
|
||||
hostname: rancher1`),
|
||||
},
|
||||
} {
|
||||
service := &MetadataService{
|
||||
Service: metadata.Service{
|
||||
Root: tt.root,
|
||||
Client: &test.HTTPClient{Resources: tt.resources, Err: tt.clientErr},
|
||||
},
|
||||
}
|
||||
data, err := service.FetchUserdata()
|
||||
if Error(err) != Error(tt.expectErr) {
|
||||
t.Fatalf("bad error (%q): want %q, got %q", tt.resources, tt.expectErr, err)
|
||||
}
|
||||
if !bytes.Equal(data, tt.userdata) {
|
||||
t.Fatalf("bad userdata (%q): want %q, got %q", tt.resources, tt.userdata, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Error(err error) string {
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -19,11 +19,12 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/netconf"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
"github.com/rancher/os/config/cloudinit/pkg"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
6
config/cloudinit/datasource/metadata/digitalocean/metadata.go
Normal file → Executable file
6
config/cloudinit/datasource/metadata/digitalocean/metadata.go
Normal file → Executable file
@@ -17,12 +17,14 @@ package digitalocean
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/rancher/os/netconf"
|
||||
|
||||
"net"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
3
config/cloudinit/datasource/metadata/digitalocean/metadata_test.go
Normal file → Executable file
3
config/cloudinit/datasource/metadata/digitalocean/metadata_test.go
Normal file → Executable file
@@ -20,11 +20,12 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/rancher/os/netconf"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/test"
|
||||
"github.com/rancher/os/config/cloudinit/pkg"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
)
|
||||
|
||||
func TestType(t *testing.T) {
|
||||
|
||||
@@ -20,10 +20,11 @@ import (
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/netconf"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
"github.com/rancher/os/config/cloudinit/pkg"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -36,10 +37,6 @@ const (
|
||||
defaultNVMeRootDisk = "/dev/nvme0n1"
|
||||
)
|
||||
|
||||
var (
|
||||
nvmeInstanceTypes = []string{"c5", "c5d", "i3.metal", "m5", "m5d", "r5", "r5d", "t3", "z1d"}
|
||||
)
|
||||
|
||||
type MetadataService struct {
|
||||
metadata.Service
|
||||
}
|
||||
@@ -147,11 +144,8 @@ func (ms MetadataService) FetchMetadata() (datasource.Metadata, error) {
|
||||
// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html
|
||||
metadata.RootDisk = defaultXVRootDisk
|
||||
if instanceType, err := ms.FetchAttribute("instance-type"); err == nil {
|
||||
for _, nvmeType := range nvmeInstanceTypes {
|
||||
if strings.HasPrefix(instanceType, nvmeType) {
|
||||
metadata.RootDisk = defaultNVMeRootDisk
|
||||
break
|
||||
}
|
||||
if strings.HasPrefix(instanceType, "m5") || strings.HasPrefix(instanceType, "c5") {
|
||||
metadata.RootDisk = defaultNVMeRootDisk
|
||||
}
|
||||
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
||||
return metadata, err
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/test"
|
||||
"github.com/rancher/os/config/cloudinit/pkg"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
"github.com/rancher/os/netconf"
|
||||
)
|
||||
|
||||
func TestType(t *testing.T) {
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
package exoscale
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
"github.com/rancher/os/config/cloudinit/pkg"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultAddress = "http://169.254.169.254/"
|
||||
apiVersion = "1.0/"
|
||||
userdataPath = apiVersion + "user-data"
|
||||
metadataPath = apiVersion + "meta-data/"
|
||||
)
|
||||
|
||||
type MetadataService struct {
|
||||
metadata.Service
|
||||
}
|
||||
|
||||
func NewDatasource(root string) *MetadataService {
|
||||
if root == "" {
|
||||
root = defaultAddress
|
||||
}
|
||||
|
||||
return &MetadataService{
|
||||
metadata.NewDatasourceWithCheckPath(
|
||||
root,
|
||||
apiVersion,
|
||||
metadataPath,
|
||||
userdataPath,
|
||||
metadataPath,
|
||||
nil,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (ms MetadataService) IsAvailable() bool {
|
||||
checkURL := ms.Root + ms.IsAvailableCheckPath
|
||||
var err error
|
||||
_, err = ms.Client.GetRetry(checkURL)
|
||||
if err != nil {
|
||||
log.Errorf("%s: %s (lastError: %v)", "IsAvailable", checkURL, err)
|
||||
}
|
||||
return (err == nil)
|
||||
}
|
||||
|
||||
func (ms MetadataService) AvailabilityChanges() bool {
|
||||
// TODO: if it can't find the network, maybe we can start it?
|
||||
return false
|
||||
}
|
||||
|
||||
func (ms MetadataService) FetchMetadata() (datasource.Metadata, error) {
|
||||
metadata := datasource.Metadata{}
|
||||
|
||||
if sshKeys, err := ms.FetchAttributes("public-keys"); err == nil {
|
||||
metadata.SSHPublicKeys = map[string]string{}
|
||||
for i, sshkey := range sshKeys {
|
||||
log.Printf("Found SSH key %d", i)
|
||||
metadata.SSHPublicKeys[strconv.Itoa(i)] = sshkey
|
||||
}
|
||||
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
||||
return metadata, err
|
||||
}
|
||||
|
||||
if hostname, err := ms.FetchAttribute("local-hostname"); err == nil {
|
||||
metadata.Hostname = strings.Split(hostname, " ")[0]
|
||||
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
||||
return metadata, err
|
||||
}
|
||||
|
||||
if localAddr, err := ms.FetchAttribute("local-ipv4"); err == nil {
|
||||
metadata.PrivateIPv4 = net.ParseIP(localAddr)
|
||||
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
||||
return metadata, err
|
||||
}
|
||||
if publicAddr, err := ms.FetchAttribute("public-ipv4"); err == nil {
|
||||
metadata.PublicIPv4 = net.ParseIP(publicAddr)
|
||||
} else if _, ok := err.(pkg.ErrNotFound); !ok {
|
||||
return metadata, err
|
||||
}
|
||||
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
func (ms MetadataService) Type() string {
|
||||
return "exoscale-metadata-service"
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package exoscale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/test"
|
||||
"github.com/rancher/os/config/cloudinit/pkg"
|
||||
)
|
||||
|
||||
func TestType(t *testing.T) {
|
||||
want := "exoscale-metadata-service"
|
||||
if kind := (MetadataService{}).Type(); kind != want {
|
||||
t.Fatalf("bad type: want %q, got %q", want, kind)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchMetadata(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
root string
|
||||
metadataPath string
|
||||
resources map[string]string
|
||||
expect datasource.Metadata
|
||||
clientErr error
|
||||
expectErr error
|
||||
}{
|
||||
{
|
||||
root: "/",
|
||||
metadataPath: "1.0/meta-data/",
|
||||
resources: map[string]string{
|
||||
"/1.0/meta-data/local-hostname": "host",
|
||||
"/1.0/meta-data/local-ipv4": "1.2.3.4",
|
||||
"/1.0/meta-data/public-ipv4": "5.6.7.8",
|
||||
"/1.0/meta-data/public-keys": "key\n",
|
||||
},
|
||||
expect: datasource.Metadata{
|
||||
Hostname: "host",
|
||||
PrivateIPv4: net.ParseIP("1.2.3.4"),
|
||||
PublicIPv4: net.ParseIP("5.6.7.8"),
|
||||
SSHPublicKeys: map[string]string{"0": "key"},
|
||||
},
|
||||
},
|
||||
{
|
||||
root: "/",
|
||||
metadataPath: "1.0/meta-data/",
|
||||
resources: map[string]string{
|
||||
"/1.0/meta-data/local-hostname": "host domain another_domain",
|
||||
"/1.0/meta-data/local-ipv4": "21.2.3.4",
|
||||
"/1.0/meta-data/public-ipv4": "25.6.7.8",
|
||||
"/1.0/meta-data/public-keys": "key\n",
|
||||
},
|
||||
expect: datasource.Metadata{
|
||||
Hostname: "host",
|
||||
PrivateIPv4: net.ParseIP("21.2.3.4"),
|
||||
PublicIPv4: net.ParseIP("25.6.7.8"),
|
||||
SSHPublicKeys: map[string]string{"0": "key"},
|
||||
},
|
||||
},
|
||||
{
|
||||
clientErr: pkg.ErrTimeout{Err: fmt.Errorf("test error")},
|
||||
expectErr: pkg.ErrTimeout{Err: fmt.Errorf("test error")},
|
||||
},
|
||||
} {
|
||||
service := &MetadataService{metadata.Service{
|
||||
Root: tt.root,
|
||||
Client: &test.HTTPClient{Resources: tt.resources, Err: tt.clientErr},
|
||||
MetadataPath: tt.metadataPath,
|
||||
}}
|
||||
metadata, err := service.FetchMetadata()
|
||||
if Error(err) != Error(tt.expectErr) {
|
||||
t.Fatalf("bad error (%q): \nwant %q, \ngot %q\n", tt.resources, tt.expectErr, err)
|
||||
}
|
||||
if !reflect.DeepEqual(tt.expect, metadata) {
|
||||
t.Fatalf("bad fetch (%q): \nwant %#v, \ngot %#v\n", tt.resources, tt.expect, metadata)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Error(err error) string {
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -21,6 +21,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
//"github.com/rancher/os/netconf"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
)
|
||||
@@ -57,19 +59,14 @@ func (ms MetadataService) FetchMetadata() (datasource.Metadata, error) {
|
||||
return datasource.Metadata{}, err
|
||||
}
|
||||
|
||||
projectSSHKeys, err := ms.fetchString("project/attributes/ssh-keys")
|
||||
projectSSHKeys, err := ms.fetchString("project/attributes/sshKeys")
|
||||
if err != nil {
|
||||
return datasource.Metadata{}, err
|
||||
}
|
||||
instanceSSHKeys, err := ms.fetchString("instance/attributes/ssh-keys")
|
||||
instanceSSHKeys, err := ms.fetchString("instance/attributes/sshKeys")
|
||||
if err != nil {
|
||||
return datasource.Metadata{}, err
|
||||
}
|
||||
blockProjectSSHKeys, err := ms.fetchString("instance/attributes/block-project-ssh-keys")
|
||||
if err != nil {
|
||||
return datasource.Metadata{}, err
|
||||
}
|
||||
|
||||
md := datasource.Metadata{
|
||||
PublicIPv4: public,
|
||||
PrivateIPv4: local,
|
||||
@@ -94,10 +91,8 @@ func (ms MetadataService) FetchMetadata() (datasource.Metadata, error) {
|
||||
md.NetworkConfig.Interfaces["eth0"] = network
|
||||
}
|
||||
*/
|
||||
keyStrings := strings.Split(instanceSSHKeys, "\n")
|
||||
if blockProjectSSHKeys != "true" {
|
||||
keyStrings = append(keyStrings, strings.Split(projectSSHKeys, "\n")...)
|
||||
}
|
||||
|
||||
keyStrings := strings.Split(projectSSHKeys+"\n"+instanceSSHKeys, "\n")
|
||||
|
||||
i := 0
|
||||
for _, keyString := range keyStrings {
|
||||
|
||||
@@ -20,6 +20,8 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
//"github.com/rancher/os/netconf"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata/test"
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/pkg"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
@@ -53,7 +53,7 @@ func (ms Service) IsAvailable() bool {
|
||||
checkURL := ms.Root + ms.IsAvailableCheckPath
|
||||
_, ms.lastError = ms.Client.Get(checkURL)
|
||||
if ms.lastError != nil {
|
||||
log.Errorf("%s: %s (lastError: %v)", "IsAvailable", checkURL, ms.lastError)
|
||||
log.Errorf("%s: %s (lastError: %s)", "IsAvailable", checkURL, ms.lastError)
|
||||
}
|
||||
return (ms.lastError == nil)
|
||||
}
|
||||
@@ -63,7 +63,7 @@ func (ms *Service) Finish() error {
|
||||
}
|
||||
|
||||
func (ms *Service) String() string {
|
||||
return fmt.Sprintf("%s: %s (lastError: %v)", "metadata", ms.UserdataURL(), ms.lastError)
|
||||
return fmt.Sprintf("%s: %s (lastError: %s)", "metadata", ms.UserdataURL(), ms.lastError)
|
||||
}
|
||||
|
||||
func (ms Service) AvailabilityChanges() bool {
|
||||
|
||||
@@ -21,8 +21,8 @@ import (
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/metadata"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/netconf"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
packetMetadata "github.com/packethost/packngo/metadata"
|
||||
|
||||
@@ -20,9 +20,10 @@ import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/log"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/pkg"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -56,7 +57,7 @@ func (c *ProcCmdline) Finish() error {
|
||||
}
|
||||
|
||||
func (c *ProcCmdline) String() string {
|
||||
return fmt.Sprintf("%s: %s (lastError: %v)", c.Type(), c.Location, c.lastError)
|
||||
return fmt.Sprintf("%s: %s (lastError: %s)", c.Type(), c.Location, c.lastError)
|
||||
}
|
||||
|
||||
func (c *ProcCmdline) AvailabilityChanges() bool {
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
package proxmox
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"syscall"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
)
|
||||
|
||||
const (
|
||||
configDev = "/dev/sr0"
|
||||
configDevMountPoint = "/media/pve-config"
|
||||
)
|
||||
|
||||
type Proxmox struct {
|
||||
root string
|
||||
readFile func(filename string) ([]byte, error)
|
||||
lastError error
|
||||
availabilityChanges bool
|
||||
}
|
||||
|
||||
func NewDataSource(root string) *Proxmox {
|
||||
return &Proxmox{root, ioutil.ReadFile, nil, true}
|
||||
}
|
||||
|
||||
func (pve *Proxmox) IsAvailable() bool {
|
||||
if pve.root == configDevMountPoint {
|
||||
pve.lastError = MountConfigDrive()
|
||||
if pve.lastError != nil {
|
||||
log.Error(pve.lastError)
|
||||
pve.availabilityChanges = false
|
||||
return false
|
||||
}
|
||||
defer pve.Finish()
|
||||
}
|
||||
|
||||
_, pve.lastError = os.Stat(pve.root)
|
||||
return !os.IsNotExist(pve.lastError)
|
||||
}
|
||||
|
||||
func (pve *Proxmox) Finish() error {
|
||||
return UnmountConfigDrive()
|
||||
}
|
||||
|
||||
func (pve *Proxmox) String() string {
|
||||
if pve.lastError != nil {
|
||||
return fmt.Sprintf("%s: %s (lastError: %v)", pve.Type(), pve.root, pve.lastError)
|
||||
}
|
||||
return fmt.Sprintf("%s: %s", pve.Type(), pve.root)
|
||||
}
|
||||
|
||||
func (pve *Proxmox) AvailabilityChanges() bool {
|
||||
return pve.availabilityChanges
|
||||
}
|
||||
|
||||
func (pve *Proxmox) ConfigRoot() string {
|
||||
return pve.root
|
||||
}
|
||||
|
||||
func (pve *Proxmox) FetchMetadata() (metadata datasource.Metadata, err error) {
|
||||
return datasource.Metadata{}, nil
|
||||
}
|
||||
|
||||
func (pve *Proxmox) FetchUserdata() ([]byte, error) {
|
||||
return pve.tryReadFile(path.Join(pve.root, "user-data"))
|
||||
}
|
||||
|
||||
func (pve *Proxmox) Type() string {
|
||||
return "proxmox"
|
||||
}
|
||||
|
||||
func (pve *Proxmox) tryReadFile(filename string) ([]byte, error) {
|
||||
if pve.root == configDevMountPoint {
|
||||
pve.lastError = MountConfigDrive()
|
||||
if pve.lastError != nil {
|
||||
log.Error(pve.lastError)
|
||||
return nil, pve.lastError
|
||||
}
|
||||
defer pve.Finish()
|
||||
}
|
||||
log.Debugf("Attempting to read from %q\n", filename)
|
||||
data, err := pve.readFile(filename)
|
||||
if os.IsNotExist(err) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
log.Errorf("ERROR read cloud-config file(%s) - err: %q", filename, err)
|
||||
}
|
||||
return data, err
|
||||
}
|
||||
|
||||
func MountConfigDrive() error {
|
||||
if err := os.MkdirAll(configDevMountPoint, 700); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fsType, err := util.GetFsType(configDev)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mount.Mount(configDev, configDevMountPoint, fsType, "ro")
|
||||
}
|
||||
|
||||
func UnmountConfigDrive() error {
|
||||
return syscall.Unmount(configDevMountPoint, 0)
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package proxmox
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource/test"
|
||||
)
|
||||
|
||||
func TestFetchUserdata(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
root string
|
||||
files test.MockFilesystem
|
||||
userdata string
|
||||
}{
|
||||
{
|
||||
root: "/",
|
||||
files: test.NewMockFilesystem(),
|
||||
userdata: "",
|
||||
},
|
||||
{
|
||||
root: "/media/config",
|
||||
files: test.NewMockFilesystem(test.File{Path: "/media/config/user-data", Contents: "userdata"}),
|
||||
userdata: "userdata",
|
||||
},
|
||||
} {
|
||||
pve := Proxmox{tt.root, tt.files.ReadFile, nil, true}
|
||||
userdata, err := pve.FetchUserdata()
|
||||
if err != nil {
|
||||
t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err)
|
||||
}
|
||||
if string(userdata) != tt.userdata {
|
||||
t.Fatalf("bad userdata for %+v: want %q, got %q", tt, tt.userdata, userdata)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigRoot(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
root string
|
||||
configRoot string
|
||||
}{
|
||||
{
|
||||
root: "/",
|
||||
configRoot: "/",
|
||||
},
|
||||
{
|
||||
root: "/media/pve-config",
|
||||
configRoot: "/media/pve-config",
|
||||
},
|
||||
} {
|
||||
pve := Proxmox{tt.root, nil, nil, true}
|
||||
if configRoot := pve.ConfigRoot(); configRoot != tt.configRoot {
|
||||
t.Fatalf("bad config root for %q: want %q, got %q", tt, tt.configRoot, configRoot)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDataSource(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
root string
|
||||
expectRoot string
|
||||
}{
|
||||
{
|
||||
root: "",
|
||||
expectRoot: "",
|
||||
},
|
||||
{
|
||||
root: "/media/pve-config",
|
||||
expectRoot: "/media/pve-config",
|
||||
},
|
||||
} {
|
||||
service := NewDataSource(tt.root)
|
||||
if service.root != tt.expectRoot {
|
||||
t.Fatalf("bad root (%q): want %q, got %q", tt.root, tt.expectRoot, service.root)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package tftp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
|
||||
"github.com/pin/tftp"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
Receive(filename string, mode string) (io.WriterTo, error)
|
||||
}
|
||||
|
||||
type RemoteFile struct {
|
||||
host string
|
||||
path string
|
||||
client Client
|
||||
stream io.WriterTo
|
||||
lastError error
|
||||
}
|
||||
|
||||
func NewDatasource(hostAndPath string) *RemoteFile {
|
||||
parts := strings.SplitN(hostAndPath, "/", 2)
|
||||
|
||||
if len(parts) < 2 {
|
||||
return &RemoteFile{hostAndPath, "", nil, nil, nil}
|
||||
}
|
||||
|
||||
host := parts[0]
|
||||
if match, _ := regexp.MatchString(":[0-9]{2,5}$", host); !match {
|
||||
// No port, using default port 69
|
||||
host += ":69"
|
||||
}
|
||||
|
||||
path := parts[1]
|
||||
if client, lastError := tftp.NewClient(host); lastError == nil {
|
||||
return &RemoteFile{host, path, client, nil, nil}
|
||||
}
|
||||
|
||||
return &RemoteFile{host, path, nil, nil, nil}
|
||||
}
|
||||
|
||||
func (f *RemoteFile) IsAvailable() bool {
|
||||
f.stream, f.lastError = f.client.Receive(f.path, "octet")
|
||||
return f.lastError == nil
|
||||
}
|
||||
|
||||
func (f *RemoteFile) Finish() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *RemoteFile) String() string {
|
||||
return fmt.Sprintf("%s, host:%s, path:%s (lastError: %v)", f.Type(), f.host, f.path, f.lastError)
|
||||
}
|
||||
|
||||
func (f *RemoteFile) AvailabilityChanges() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *RemoteFile) ConfigRoot() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *RemoteFile) FetchMetadata() (datasource.Metadata, error) {
|
||||
return datasource.Metadata{}, nil
|
||||
}
|
||||
|
||||
func (f *RemoteFile) FetchUserdata() ([]byte, error) {
|
||||
var b bytes.Buffer
|
||||
|
||||
_, err := f.stream.WriteTo(&b)
|
||||
|
||||
return b.Bytes(), err
|
||||
}
|
||||
|
||||
func (f *RemoteFile) Type() string {
|
||||
return "tftp"
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package tftp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type mockClient struct {
|
||||
}
|
||||
|
||||
type mockReceiver struct {
|
||||
}
|
||||
|
||||
func (r mockReceiver) WriteTo(w io.Writer) (n int64, err error) {
|
||||
b := []byte("cloud-config file")
|
||||
w.Write(b)
|
||||
return int64(len(b)), nil
|
||||
}
|
||||
|
||||
func (c mockClient) Receive(filename string, mode string) (io.WriterTo, error) {
|
||||
if filename == "does-not-exist" {
|
||||
return &mockReceiver{}, fmt.Errorf("does not exist")
|
||||
}
|
||||
return &mockReceiver{}, nil
|
||||
}
|
||||
|
||||
var _ Client = (*mockClient)(nil)
|
||||
|
||||
func TestNewDatasource(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
root string
|
||||
expectHost string
|
||||
expectPath string
|
||||
}{
|
||||
{
|
||||
root: "127.0.0.1/test/file.yaml",
|
||||
expectHost: "127.0.0.1:69",
|
||||
expectPath: "test/file.yaml",
|
||||
},
|
||||
{
|
||||
root: "127.0.0.1/test/file.yaml",
|
||||
expectHost: "127.0.0.1:69",
|
||||
expectPath: "test/file.yaml",
|
||||
},
|
||||
} {
|
||||
ds := NewDatasource(tt.root)
|
||||
if ds.host != tt.expectHost || ds.path != tt.expectPath {
|
||||
t.Fatalf("bad host or path (%q): want host=%s, got %s, path=%s, got %s", tt.root, tt.expectHost, ds.host, tt.expectPath, ds.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsAvailable(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
remoteFile *RemoteFile
|
||||
expect bool
|
||||
}{
|
||||
{
|
||||
remoteFile: &RemoteFile{"1.2.3.4", "test", &mockClient{}, nil, nil},
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
remoteFile: &RemoteFile{"1.2.3.4", "does-not-exist", &mockClient{}, nil, nil},
|
||||
expect: false,
|
||||
},
|
||||
} {
|
||||
if tt.remoteFile.IsAvailable() != tt.expect {
|
||||
t.Fatalf("expected remote file %s to be %v", tt.remoteFile.path, tt.expect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchUserdata(t *testing.T) {
|
||||
rf := &RemoteFile{"1.2.3.4", "test", &mockClient{}, &mockReceiver{}, nil}
|
||||
b, _ := rf.FetchUserdata()
|
||||
|
||||
expect := []byte("cloud-config file")
|
||||
|
||||
if len(b) != len(expect) || !reflect.DeepEqual(b, expect) {
|
||||
t.Fatalf("expected length of buffer to be %d was %d. Expected %s, got %s", len(expect), len(b), string(expect), string(b))
|
||||
}
|
||||
}
|
||||
|
||||
func TestType(t *testing.T) {
|
||||
rf := &RemoteFile{"1.2.3.4", "test", &mockClient{}, nil, nil}
|
||||
|
||||
if rf.Type() != "tftp" {
|
||||
t.Fatalf("expected remote file Type() to return %s got %s", "tftp", rf.Type())
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/pkg"
|
||||
"github.com/rancher/os/pkg/util/network"
|
||||
"github.com/rancher/os/util/network"
|
||||
)
|
||||
|
||||
type RemoteFile struct {
|
||||
@@ -43,7 +43,7 @@ func (f *RemoteFile) Finish() error {
|
||||
}
|
||||
|
||||
func (f *RemoteFile) String() string {
|
||||
return fmt.Sprintf("%s: %s (lastError: %v)", f.Type(), f.url, f.lastError)
|
||||
return fmt.Sprintf("%s: %s (lastError: %s)", f.Type(), f.url, f.lastError)
|
||||
}
|
||||
|
||||
func (f *RemoteFile) AvailabilityChanges() bool {
|
||||
|
||||
@@ -21,8 +21,8 @@ import (
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/config"
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/netconf"
|
||||
)
|
||||
|
||||
type readConfigFunction func(key string) (string, error)
|
||||
@@ -40,7 +40,7 @@ func (v VMWare) Finish() error {
|
||||
}
|
||||
|
||||
func (v VMWare) String() string {
|
||||
return fmt.Sprintf("%s: %s (lastError: %v)", v.Type(), v.ovfFileName, v.lastError)
|
||||
return fmt.Sprintf("%s: %s (lastError: %s)", v.Type(), v.ovfFileName, v.lastError)
|
||||
}
|
||||
|
||||
func (v VMWare) AvailabilityChanges() bool {
|
||||
@@ -77,13 +77,6 @@ func (v VMWare) FetchMetadata() (metadata datasource.Metadata, err error) {
|
||||
}
|
||||
metadata.NetworkConfig.DNS.Nameservers = append(metadata.NetworkConfig.DNS.Nameservers, val)
|
||||
}
|
||||
dnsServers, _ := v.read("dns.servers")
|
||||
for _, val := range strings.Split(dnsServers, ",") {
|
||||
if val == "" {
|
||||
break
|
||||
}
|
||||
metadata.NetworkConfig.DNS.Nameservers = append(metadata.NetworkConfig.DNS.Nameservers, val)
|
||||
}
|
||||
|
||||
for i := 0; ; i++ {
|
||||
//if domain := saveConfig("dns.domain.%d", i); domain == "" {
|
||||
@@ -93,13 +86,6 @@ func (v VMWare) FetchMetadata() (metadata datasource.Metadata, err error) {
|
||||
}
|
||||
metadata.NetworkConfig.DNS.Search = append(metadata.NetworkConfig.DNS.Search, val)
|
||||
}
|
||||
dnsDomains, _ := v.read("dns.domains")
|
||||
for _, val := range strings.Split(dnsDomains, ",") {
|
||||
if val == "" {
|
||||
break
|
||||
}
|
||||
metadata.NetworkConfig.DNS.Search = append(metadata.NetworkConfig.DNS.Search, val)
|
||||
}
|
||||
|
||||
metadata.NetworkConfig.Interfaces = make(map[string]netconf.InterfaceConfig)
|
||||
found := true
|
||||
@@ -134,11 +120,6 @@ func (v VMWare) FetchMetadata() (metadata datasource.Metadata, err error) {
|
||||
if address == "" {
|
||||
break
|
||||
}
|
||||
netmask, _ := v.read("interface.%d.ip.%d.netmask", i, a)
|
||||
if netmask != "" {
|
||||
ones, _ := net.IPMask(net.ParseIP(netmask).To4()).Size()
|
||||
address = fmt.Sprintf("%s/%d", address, ones)
|
||||
}
|
||||
netDevice.Addresses = append(netDevice.Addresses, address)
|
||||
found = true
|
||||
netDevice.DHCP = false
|
||||
|
||||
@@ -18,9 +18,10 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/pkg"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
"github.com/sigma/vmw-guestinfo/rpcvmx"
|
||||
"github.com/sigma/vmw-guestinfo/vmcheck"
|
||||
@@ -32,10 +33,7 @@ type ovfWrapper struct {
|
||||
}
|
||||
|
||||
func (ovf ovfWrapper) readConfig(key string) (string, error) {
|
||||
if val := ovf.env.Properties["guestinfo."+key]; val != "" {
|
||||
return val, nil
|
||||
}
|
||||
return readConfig(key)
|
||||
return ovf.env.Properties["guestinfo."+key], nil
|
||||
}
|
||||
|
||||
func NewDatasource(fileName string) *VMWare {
|
||||
@@ -80,14 +78,9 @@ func (v VMWare) IsAvailable() bool {
|
||||
}
|
||||
if v.ovfFileName != "" {
|
||||
_, v.lastError = os.Stat(v.ovfFileName)
|
||||
if !os.IsNotExist(v.lastError) {
|
||||
// when GuestInfo is empty, the DataSource should not be available.
|
||||
return v.checkGuestInfo()
|
||||
}
|
||||
return false
|
||||
return !os.IsNotExist(v.lastError)
|
||||
}
|
||||
// when GuestInfo is empty, the DataSource should not be available.
|
||||
return vmcheck.IsVirtualWorld() && v.checkGuestInfo()
|
||||
return vmcheck.IsVirtualWorld()
|
||||
}
|
||||
|
||||
func readConfig(key string) (string, error) {
|
||||
@@ -114,23 +107,3 @@ func urlDownload(url string) ([]byte, error) {
|
||||
client := pkg.NewHTTPClient()
|
||||
return client.GetRetry(url)
|
||||
}
|
||||
|
||||
func (v VMWare) checkGuestInfo() bool {
|
||||
userData, err := v.FetchUserdata()
|
||||
if err == nil && string(userData) != "" {
|
||||
return true
|
||||
}
|
||||
metadata, err := v.FetchMetadata()
|
||||
if err == nil {
|
||||
if metadata.Hostname != "" {
|
||||
return true
|
||||
}
|
||||
if len(metadata.NetworkConfig.DNS.Nameservers) > 0 || len(metadata.NetworkConfig.DNS.Search) > 0 {
|
||||
return true
|
||||
}
|
||||
if len(metadata.NetworkConfig.Interfaces) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
"github.com/rancher/os/netconf"
|
||||
)
|
||||
|
||||
type MockHypervisor map[string]string
|
||||
@@ -361,8 +361,8 @@ func TestOvfTransport(t *testing.T) {
|
||||
}
|
||||
v.urlDownload = fakeDownloader
|
||||
|
||||
metadata, _ := v.FetchMetadata()
|
||||
userdata, _ := v.FetchUserdata()
|
||||
metadata, err := v.FetchMetadata()
|
||||
userdata, err := v.FetchUserdata()
|
||||
|
||||
if !reflect.DeepEqual(tt.metadata, metadata) {
|
||||
t.Errorf("bad metadata (#%d): want %#v, got %#v", i, tt.metadata, metadata)
|
||||
|
||||
128
config/cloudinit/datasource/waagent/waagent.go
Normal file
128
config/cloudinit/datasource/waagent/waagent.go
Normal file
@@ -0,0 +1,128 @@
|
||||
// Copyright 2015 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package waagent
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/rancher/os/log"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
)
|
||||
|
||||
type Waagent struct {
|
||||
root string
|
||||
readFile func(filename string) ([]byte, error)
|
||||
lastError error
|
||||
}
|
||||
|
||||
func NewDatasource(root string) *Waagent {
|
||||
return &Waagent{root, ioutil.ReadFile, nil}
|
||||
}
|
||||
|
||||
func (a *Waagent) IsAvailable() bool {
|
||||
_, a.lastError = os.Stat(path.Join(a.root, "provisioned"))
|
||||
return !os.IsNotExist(a.lastError)
|
||||
}
|
||||
|
||||
func (a *Waagent) Finish() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Waagent) String() string {
|
||||
return fmt.Sprintf("%s: %s (lastError: %s)", a.Type(), a.root, a.lastError)
|
||||
}
|
||||
|
||||
func (a *Waagent) AvailabilityChanges() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (a *Waagent) ConfigRoot() string {
|
||||
return a.root
|
||||
}
|
||||
|
||||
func (a *Waagent) FetchMetadata() (metadata datasource.Metadata, err error) {
|
||||
var metadataBytes []byte
|
||||
if metadataBytes, err = a.tryReadFile(path.Join(a.root, "SharedConfig.xml")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(metadataBytes) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
type Instance struct {
|
||||
ID string `xml:"id,attr"`
|
||||
Address string `xml:"address,attr"`
|
||||
InputEndpoints struct {
|
||||
Endpoints []struct {
|
||||
LoadBalancedPublicAddress string `xml:"loadBalancedPublicAddress,attr"`
|
||||
} `xml:"Endpoint"`
|
||||
}
|
||||
}
|
||||
|
||||
type SharedConfig struct {
|
||||
Incarnation struct {
|
||||
Instance string `xml:"instance,attr"`
|
||||
}
|
||||
Instances struct {
|
||||
Instances []Instance `xml:"Instance"`
|
||||
}
|
||||
}
|
||||
|
||||
var m SharedConfig
|
||||
if err = xml.Unmarshal(metadataBytes, &m); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var instance Instance
|
||||
for _, i := range m.Instances.Instances {
|
||||
if i.ID == m.Incarnation.Instance {
|
||||
instance = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
metadata.PrivateIPv4 = net.ParseIP(instance.Address)
|
||||
for _, e := range instance.InputEndpoints.Endpoints {
|
||||
host, _, err := net.SplitHostPort(e.LoadBalancedPublicAddress)
|
||||
if err == nil {
|
||||
metadata.PublicIPv4 = net.ParseIP(host)
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (a *Waagent) FetchUserdata() ([]byte, error) {
|
||||
return a.tryReadFile(path.Join(a.root, "CustomData"))
|
||||
}
|
||||
|
||||
func (a *Waagent) Type() string {
|
||||
return "Waagent"
|
||||
}
|
||||
|
||||
func (a *Waagent) tryReadFile(filename string) ([]byte, error) {
|
||||
log.Printf("Attempting to read from %q\n", filename)
|
||||
data, err := a.readFile(filename)
|
||||
if os.IsNotExist(err) {
|
||||
err = nil
|
||||
}
|
||||
return data, err
|
||||
}
|
||||
166
config/cloudinit/datasource/waagent/waagent_test.go
Normal file
166
config/cloudinit/datasource/waagent/waagent_test.go
Normal file
@@ -0,0 +1,166 @@
|
||||
// Copyright 2015 CoreOS, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package waagent
|
||||
|
||||
import (
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/datasource/test"
|
||||
)
|
||||
|
||||
func TestFetchMetadata(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
root string
|
||||
files test.MockFilesystem
|
||||
metadata datasource.Metadata
|
||||
}{
|
||||
{
|
||||
root: "/",
|
||||
files: test.NewMockFilesystem(),
|
||||
},
|
||||
{
|
||||
root: "/",
|
||||
files: test.NewMockFilesystem(test.File{Path: "/SharedConfig.xml", Contents: ""}),
|
||||
},
|
||||
{
|
||||
root: "/var/lib/Waagent",
|
||||
files: test.NewMockFilesystem(test.File{Path: "/var/lib/Waagent/SharedConfig.xml", Contents: ""}),
|
||||
},
|
||||
{
|
||||
root: "/var/lib/Waagent",
|
||||
files: test.NewMockFilesystem(test.File{Path: "/var/lib/Waagent/SharedConfig.xml", Contents: `<?xml version="1.0" encoding="utf-8"?>
|
||||
<SharedConfig version="1.0.0.0" goalStateIncarnation="1">
|
||||
<Deployment name="c8f9e4c9c18948e1bebf57c5685da756" guid="{1d10394f-c741-4a1a-a6bb-278f213c5a5e}" incarnation="0" isNonCancellableTopologyChangeEnabled="false">
|
||||
<Service name="core-test-1" guid="{00000000-0000-0000-0000-000000000000}" />
|
||||
<ServiceInstance name="c8f9e4c9c18948e1bebf57c5685da756.0" guid="{1e202e9a-8ffe-4915-b6ef-4118c9628fda}" />
|
||||
</Deployment>
|
||||
<Incarnation number="1" instance="core-test-1" guid="{8767eb4b-b445-4783-b1f5-6c0beaf41ea0}" />
|
||||
<Role guid="{53ecc81e-257f-fbc9-a53a-8cf1a0a122b4}" name="core-test-1" settleTimeSeconds="0" />
|
||||
<LoadBalancerSettings timeoutSeconds="0" waitLoadBalancerProbeCount="8">
|
||||
<Probes>
|
||||
<Probe name="D41D8CD98F00B204E9800998ECF8427E" />
|
||||
<Probe name="C9DEC1518E1158748FA4B6081A8266DD" />
|
||||
</Probes>
|
||||
</LoadBalancerSettings>
|
||||
<OutputEndpoints>
|
||||
<Endpoint name="core-test-1:openInternalEndpoint" type="SFS">
|
||||
<Target instance="core-test-1" endpoint="openInternalEndpoint" />
|
||||
</Endpoint>
|
||||
</OutputEndpoints>
|
||||
<Instances>
|
||||
<Instance id="core-test-1" address="100.73.202.64">
|
||||
<FaultDomains randomId="0" updateId="0" updateCount="0" />
|
||||
<InputEndpoints>
|
||||
<Endpoint name="openInternalEndpoint" address="100.73.202.64" protocol="any" isPublic="false" enableDirectServerReturn="false" isDirectAddress="false" disableStealthMode="false">
|
||||
<LocalPorts>
|
||||
<LocalPortSelfManaged />
|
||||
</LocalPorts>
|
||||
</Endpoint>
|
||||
<Endpoint name="ssh" address="100.73.202.64:22" protocol="tcp" hostName="core-test-1ContractContract" isPublic="true" loadBalancedPublicAddress="191.239.39.77:22" enableDirectServerReturn="false" isDirectAddress="false" disableStealthMode="false">
|
||||
<LocalPorts>
|
||||
<LocalPortRange from="22" to="22" />
|
||||
</LocalPorts>
|
||||
</Endpoint>
|
||||
</InputEndpoints>
|
||||
</Instance>
|
||||
</Instances>
|
||||
</SharedConfig>`}),
|
||||
metadata: datasource.Metadata{
|
||||
PrivateIPv4: net.ParseIP("100.73.202.64"),
|
||||
PublicIPv4: net.ParseIP("191.239.39.77"),
|
||||
},
|
||||
},
|
||||
} {
|
||||
a := Waagent{tt.root, tt.files.ReadFile, nil}
|
||||
metadata, err := a.FetchMetadata()
|
||||
if err != nil {
|
||||
t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err)
|
||||
}
|
||||
if !reflect.DeepEqual(tt.metadata, metadata) {
|
||||
t.Fatalf("bad metadata for %+v: want %#v, got %#v", tt, tt.metadata, metadata)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchUserdata(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
root string
|
||||
files test.MockFilesystem
|
||||
}{
|
||||
{
|
||||
"/",
|
||||
test.NewMockFilesystem(),
|
||||
},
|
||||
{
|
||||
"/",
|
||||
test.NewMockFilesystem(test.File{Path: "/CustomData", Contents: ""}),
|
||||
},
|
||||
{
|
||||
"/var/lib/Waagent/",
|
||||
test.NewMockFilesystem(test.File{Path: "/var/lib/Waagent/CustomData", Contents: ""}),
|
||||
},
|
||||
} {
|
||||
a := Waagent{tt.root, tt.files.ReadFile, nil}
|
||||
_, err := a.FetchUserdata()
|
||||
if err != nil {
|
||||
t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigRoot(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
root string
|
||||
configRoot string
|
||||
}{
|
||||
{
|
||||
"/",
|
||||
"/",
|
||||
},
|
||||
{
|
||||
"/var/lib/Waagent",
|
||||
"/var/lib/Waagent",
|
||||
},
|
||||
} {
|
||||
a := Waagent{tt.root, nil, nil}
|
||||
if configRoot := a.ConfigRoot(); configRoot != tt.configRoot {
|
||||
t.Fatalf("bad config root for %q: want %q, got %q", tt, tt.configRoot, configRoot)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDatasource(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
root string
|
||||
expectRoot string
|
||||
}{
|
||||
{
|
||||
root: "",
|
||||
expectRoot: "",
|
||||
},
|
||||
{
|
||||
root: "/var/lib/Waagent",
|
||||
expectRoot: "/var/lib/Waagent",
|
||||
},
|
||||
} {
|
||||
service := NewDatasource(tt.root)
|
||||
if service.root != tt.expectRoot {
|
||||
t.Fatalf("bad root (%q): want %q, got %q", tt.root, tt.expectRoot, service.root)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -363,7 +363,7 @@ func TestFilename(t *testing.T) {
|
||||
{logicalInterface{name: "iface", hwaddr: net.HardwareAddr([]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab}), configDepth: 1}, "01-iface"},
|
||||
} {
|
||||
if tt.i.Filename() != tt.f {
|
||||
t.Fatalf("bad filename: got %q, want %q", tt.i.Filename(), tt.f)
|
||||
t.Fatalf("bad filename (%q): got %q, want %q", tt.i, tt.i.Filename(), tt.f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ package network
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
"github.com/rancher/os/netconf"
|
||||
)
|
||||
|
||||
func ProcessPacketNetconf(netdata netconf.NetworkConfig) ([]InterfaceGenerator, error) {
|
||||
|
||||
@@ -57,7 +57,7 @@ func ProcessVMwareNetconf(config map[string]string) ([]InterfaceGenerator, error
|
||||
var dhcp bool
|
||||
iface := &physicalInterface{}
|
||||
|
||||
log.Printf("Processing interface %d", i)
|
||||
log.Printf("Proccessing interface %d", i)
|
||||
|
||||
log.Println("Processing DHCP")
|
||||
if dhcp, err = processDHCPConfig(config, fmt.Sprintf("interface.%d.", i)); err != nil {
|
||||
|
||||
@@ -18,12 +18,11 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
neturl "net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/os/pkg/log"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -121,14 +120,14 @@ func (h *HTTPClient) GetRetry(rawurl string) ([]byte, error) {
|
||||
|
||||
duration := h.InitialBackoff
|
||||
for retry := 1; retry <= h.MaxRetries; retry++ {
|
||||
log.Debugf("Fetching data from %s. Attempt #%d", dataURL, retry)
|
||||
log.Printf("Fetching data from %s. Attempt #%d", dataURL, retry)
|
||||
|
||||
data, err := h.Get(dataURL)
|
||||
switch err.(type) {
|
||||
case ErrNetwork:
|
||||
log.Debugf(err.Error())
|
||||
log.Printf(err.Error())
|
||||
case ErrServer:
|
||||
log.Debugf(err.Error())
|
||||
log.Printf(err.Error())
|
||||
case ErrNotFound:
|
||||
return data, err
|
||||
default:
|
||||
@@ -136,7 +135,7 @@ func (h *HTTPClient) GetRetry(rawurl string) ([]byte, error) {
|
||||
}
|
||||
|
||||
duration = ExpBackoff(duration, h.MaxBackoff)
|
||||
log.Debugf("Sleeping for %v...", duration)
|
||||
log.Printf("Sleeping for %v...", duration)
|
||||
time.Sleep(duration)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
source build
|
||||
source ./build
|
||||
|
||||
SRC=$(find . -name '*.go' \
|
||||
-not -path "./vendor/*")
|
||||
|
||||
@@ -3,11 +3,9 @@ package cmdline
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
func Read(parseAll bool) (m map[interface{}]interface{}, err error) {
|
||||
@@ -126,34 +124,11 @@ func UnmarshalOrReturnString(value string) (result interface{}) {
|
||||
return
|
||||
}
|
||||
|
||||
//splitCmdLine splits on spaces except when a space is within a quoted or bracketed string.
|
||||
func splitCmdLine(cmdLine string) []string {
|
||||
lastRune := rune(0)
|
||||
f := func(c rune) bool {
|
||||
switch {
|
||||
case c == lastRune:
|
||||
lastRune = rune(0)
|
||||
return false
|
||||
case lastRune != rune(0):
|
||||
return false
|
||||
case unicode.In(c, unicode.Quotation_Mark):
|
||||
lastRune = c
|
||||
return false
|
||||
case c == '[':
|
||||
lastRune = ']'
|
||||
return false
|
||||
default:
|
||||
return c == ' '
|
||||
}
|
||||
}
|
||||
return strings.FieldsFunc(cmdLine, f)
|
||||
}
|
||||
|
||||
func Parse(cmdLine string, parseAll bool) map[interface{}]interface{} {
|
||||
result := map[interface{}]interface{}{}
|
||||
result := make(map[interface{}]interface{})
|
||||
|
||||
outer:
|
||||
for _, part := range splitCmdLine(cmdLine) {
|
||||
for _, part := range strings.Split(cmdLine, " ") {
|
||||
if strings.HasPrefix(part, "cc.") {
|
||||
part = part[3:]
|
||||
} else if !strings.HasPrefix(part, "rancher.") {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
"github.com/rancher/os/config/cmdline"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const Banner = `
|
||||
|
||||
@@ -3,10 +3,10 @@ package config
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/rancher/os/config/cmdline"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
|
||||
"github.com/rancher/os/config/cmdline"
|
||||
"github.com/rancher/os/util"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -123,12 +123,6 @@ func TestCmdlineParse(t *testing.T) {
|
||||
},
|
||||
}, cmdline.Parse("rancher.key=a\nb", false), false)
|
||||
|
||||
assert.Equal(map[interface{}]interface{}{
|
||||
"rancher": map[interface{}]interface{}{
|
||||
"key": "a b",
|
||||
},
|
||||
}, cmdline.Parse("rancher.key='a b'", false), false)
|
||||
|
||||
assert.Equal(map[interface{}]interface{}{
|
||||
"rancher": map[interface{}]interface{}{
|
||||
"key": "a:b",
|
||||
@@ -164,24 +158,6 @@ func TestCmdlineParse(t *testing.T) {
|
||||
"strArray": []interface{}{"url:http://192.168.1.100/cloud-config?a=b"},
|
||||
},
|
||||
}, cmdline.Parse("rancher.strArray=[url:http://192.168.1.100/cloud-config?a=b]", false), false)
|
||||
|
||||
assert.Equal(map[interface{}]interface{}{
|
||||
"rancher": map[interface{}]interface{}{
|
||||
"strArray": []interface{}{"part1 part2", "part3"},
|
||||
},
|
||||
}, cmdline.Parse("rancher.strArray=['part1 part2',part3]", false), false)
|
||||
|
||||
assert.Equal(map[interface{}]interface{}{
|
||||
"rancher": map[interface{}]interface{}{
|
||||
"strArray": []interface{}{"part1 part2", "part3"},
|
||||
},
|
||||
}, cmdline.Parse("rancher.strArray=[\"part1 part2\",part3]", false), false)
|
||||
|
||||
assert.Equal(map[interface{}]interface{}{
|
||||
"rancher": map[interface{}]interface{}{
|
||||
"strArray": []interface{}{"part1 part2", "part3"},
|
||||
},
|
||||
}, cmdline.Parse("rancher.strArray=[ \"part1 part2\", part3 ]", false), false)
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
type CfgFunc func(*CloudConfig) (*CloudConfig, error)
|
||||
|
||||
@@ -9,16 +9,14 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/initialize"
|
||||
"github.com/rancher/os/config/cmdline"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
"github.com/docker/engine-api/types"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
"github.com/rancher/os/config/cloudinit/datasource"
|
||||
"github.com/rancher/os/config/cloudinit/initialize"
|
||||
"github.com/rancher/os/config/cmdline"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
func ReadConfig(bytes []byte, substituteMetadataVars bool, files ...string) (*CloudConfig, error) {
|
||||
@@ -49,21 +47,6 @@ func loadRawDiskConfig(dirPrefix string, full bool) map[interface{}]interface{}
|
||||
return util.Merge(rawCfg, additionalCfgs)
|
||||
}
|
||||
|
||||
func loadRawDiskConfigWithError(dirPrefix string, full bool) (map[interface{}]interface{}, error) {
|
||||
var rawCfg map[interface{}]interface{}
|
||||
rawCfg, err := readConfigs(nil, true, true, OsConfigFile, OemConfigFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files := CloudConfigDirFiles(dirPrefix)
|
||||
files = append(files, path.Join(dirPrefix, CloudConfigFile))
|
||||
additionalCfgs, err := readConfigs(nil, true, true, files...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return util.Merge(rawCfg, additionalCfgs), nil
|
||||
}
|
||||
|
||||
func loadRawConfig(dirPrefix string, full bool) map[interface{}]interface{} {
|
||||
rawCfg := loadRawDiskConfig(dirPrefix, full)
|
||||
procCmdline, err := cmdline.Read(false)
|
||||
@@ -76,21 +59,6 @@ func loadRawConfig(dirPrefix string, full bool) map[interface{}]interface{} {
|
||||
return mergeMetadata(rawCfg, readMetadata())
|
||||
}
|
||||
|
||||
func loadRawConfigWithError(dirPrefix string, full bool) (map[interface{}]interface{}, error) {
|
||||
rawCfg, err := loadRawDiskConfigWithError(dirPrefix, full)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
procCmdline, err := cmdline.Read(false)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Error("Failed to read kernel params")
|
||||
}
|
||||
rawCfg = util.Merge(rawCfg, procCmdline)
|
||||
rawCfg = util.Merge(rawCfg, readElidedCmdline(rawCfg))
|
||||
rawCfg = applyDebugFlags(rawCfg)
|
||||
return mergeMetadata(rawCfg, readMetadata()), nil
|
||||
}
|
||||
|
||||
func LoadConfig() *CloudConfig {
|
||||
cfg := LoadConfigWithPrefix("")
|
||||
|
||||
@@ -103,21 +71,6 @@ func LoadConfig() *CloudConfig {
|
||||
return cfg
|
||||
}
|
||||
|
||||
func LoadConfigWithError() (*CloudConfig, *gojsonschema.Result, error) {
|
||||
rawCfg, err := loadRawConfigWithError("", true)
|
||||
if err != nil {
|
||||
return &CloudConfig{}, nil, err
|
||||
}
|
||||
cfg := &CloudConfig{}
|
||||
if err := util.Convert(rawCfg, cfg); err != nil {
|
||||
validationErrors, err := ValidateRawCfg(rawCfg)
|
||||
return &CloudConfig{}, validationErrors, err
|
||||
}
|
||||
cfg = amendNils(cfg)
|
||||
cfg = amendContainerNames(cfg)
|
||||
return cfg, nil, nil
|
||||
}
|
||||
|
||||
func LoadConfigWithPrefix(dirPrefix string) *CloudConfig {
|
||||
rawCfg := loadRawConfig(dirPrefix, true)
|
||||
|
||||
|
||||
374
config/schema.go
374
config/schema.go
@@ -1,218 +1,208 @@
|
||||
package config
|
||||
|
||||
var schema = `{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"ssh_authorized_keys": {"$ref": "#/definitions/list_of_strings"},
|
||||
"write_files": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/definitions/file_config"}
|
||||
},
|
||||
"hostname": {"type": "string"},
|
||||
"mounts": {"type": "array"},
|
||||
"rancher": {"$ref": "#/definitions/rancher_config"},
|
||||
"runcmd": {"type": "array"},
|
||||
"bootcmd": {"type": "array"}
|
||||
},
|
||||
"properties": {
|
||||
"ssh_authorized_keys": {"$ref": "#/definitions/list_of_strings"},
|
||||
"write_files": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/definitions/file_config"}
|
||||
},
|
||||
"hostname": {"type": "string"},
|
||||
"mounts": {"type": "array"},
|
||||
"rancher": {"$ref": "#/definitions/rancher_config"},
|
||||
"runcmd": {"type": "array"},
|
||||
"bootcmd": {"type": "array"}
|
||||
},
|
||||
|
||||
"definitions": {
|
||||
"rancher_config": {
|
||||
"id": "#/definitions/rancher_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"definitions": {
|
||||
"rancher_config": {
|
||||
"id": "#/definitions/rancher_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"console": {"type": "string"},
|
||||
"environment": {"type": "object"},
|
||||
"cloud_init_services": {"type": "object"},
|
||||
"services": {"type": "object"},
|
||||
"bootstrap": {"type": "object"},
|
||||
"autoformat": {"type": "object"},
|
||||
"bootstrap_docker": {"$ref": "#/definitions/docker_config"},
|
||||
"cloud_init": {"$ref": "#/definitions/cloud_init_config"},
|
||||
"debug": {"type": "boolean"},
|
||||
"rm_usr": {"type": "boolean"},
|
||||
"no_sharedroot": {"type": "boolean"},
|
||||
"log": {"type": "boolean"},
|
||||
"force_console_rebuild": {"type": "boolean"},
|
||||
"recovery": {"type": "boolean"},
|
||||
"disable": {"$ref": "#/definitions/list_of_strings"},
|
||||
"services_include": {"type": "object"},
|
||||
"modules": {"$ref": "#/definitions/list_of_strings"},
|
||||
"network": {"$ref": "#/definitions/network_config"},
|
||||
"repositories": {"type": "object"},
|
||||
"ssh": {"$ref": "#/definitions/ssh_config"},
|
||||
"state": {"$ref": "#/definitions/state_config"},
|
||||
"system_docker": {"$ref": "#/definitions/docker_config"},
|
||||
"upgrade": {"$ref": "#/definitions/upgrade_config"},
|
||||
"docker": {"$ref": "#/definitions/docker_config"},
|
||||
"registry_auths": {"type": "object"},
|
||||
"defaults": {"$ref": "#/definitions/defaults_config"},
|
||||
"resize_device": {"type": "string"},
|
||||
"sysctl": {"type": "object"},
|
||||
"restart_services": {"type": "array"},
|
||||
"hypervisor_service": {"type": "boolean"},
|
||||
"shutdown_timeout": {"type": "integer"},
|
||||
"http_load_retries": {"type": "integer"},
|
||||
"preload_wait": {"type": "boolean"}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"console": {"type": "string"},
|
||||
"environment": {"type": "object"},
|
||||
"cloud_init_services": {"type": "object"},
|
||||
"services": {"type": "object"},
|
||||
"bootstrap": {"type": "object"},
|
||||
"autoformat": {"type": "object"},
|
||||
"bootstrap_docker": {"$ref": "#/definitions/docker_config"},
|
||||
"cloud_init": {"$ref": "#/definitions/cloud_init_config"},
|
||||
"debug": {"type": "boolean"},
|
||||
"rm_usr": {"type": "boolean"},
|
||||
"no_sharedroot": {"type": "boolean"},
|
||||
"log": {"type": "boolean"},
|
||||
"force_console_rebuild": {"type": "boolean"},
|
||||
"recovery": {"type": "boolean"},
|
||||
"disable": {"$ref": "#/definitions/list_of_strings"},
|
||||
"services_include": {"type": "object"},
|
||||
"modules": {"$ref": "#/definitions/list_of_strings"},
|
||||
"network": {"$ref": "#/definitions/network_config"},
|
||||
"default_network": {"type": "object"},
|
||||
"repositories": {"type": "object"},
|
||||
"ssh": {"$ref": "#/definitions/ssh_config"},
|
||||
"state": {"$ref": "#/definitions/state_config"},
|
||||
"system_docker": {"$ref": "#/definitions/docker_config"},
|
||||
"upgrade": {"$ref": "#/definitions/upgrade_config"},
|
||||
"docker": {"$ref": "#/definitions/docker_config"},
|
||||
"registry_auths": {"type": "object"},
|
||||
"defaults": {"$ref": "#/definitions/defaults_config"},
|
||||
"resize_device": {"type": "string"},
|
||||
"sysctl": {"type": "object"},
|
||||
"restart_services": {"type": "array"},
|
||||
"hypervisor_service": {"type": "boolean"},
|
||||
"shutdown_timeout": {"type": "integer"},
|
||||
"preload_wait": {"type": "boolean"}
|
||||
}
|
||||
},
|
||||
|
||||
"file_config": {
|
||||
"id": "#/definitions/file_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"file_config": {
|
||||
"id": "#/definitions/file_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"encoding": {"type": "string"},
|
||||
"container": {"type": "string"},
|
||||
"content": {"type": "string"},
|
||||
"owner": {"type": "string"},
|
||||
"path": {"type": "string"},
|
||||
"permissions": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"encoding": {"type": "string"},
|
||||
"container": {"type": "string"},
|
||||
"content": {"type": "string"},
|
||||
"owner": {"type": "string"},
|
||||
"path": {"type": "string"},
|
||||
"permissions": {"type": "string"}
|
||||
}
|
||||
},
|
||||
|
||||
"network_config": {
|
||||
"id": "#/definitions/network_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"network_config": {
|
||||
"id": "#/definitions/network_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"pre_cmds": {"$ref": "#/definitions/list_of_strings"},
|
||||
"dhcp_timeout": {"type": "integer"},
|
||||
"dns": {"type": "object"},
|
||||
"interfaces": {"type": "object"},
|
||||
"post_cmds": {"$ref": "#/definitions/list_of_strings"},
|
||||
"http_proxy": {"type": "string"},
|
||||
"https_proxy": {"type": "string"},
|
||||
"no_proxy": {"type": "string"},
|
||||
"wifi_networks": {"type": "object"},
|
||||
"modem_networks": {"type": "object"}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"pre_cmds": {"$ref": "#/definitions/list_of_strings"},
|
||||
"dns": {"type": "object"},
|
||||
"interfaces": {"type": "object"},
|
||||
"post_cmds": {"$ref": "#/definitions/list_of_strings"},
|
||||
"http_proxy": {"type": "string"},
|
||||
"https_proxy": {"type": "string"},
|
||||
"no_proxy": {"type": "string"}
|
||||
}
|
||||
},
|
||||
|
||||
"upgrade_config": {
|
||||
"id": "#/definitions/upgrade_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"upgrade_config": {
|
||||
"id": "#/definitions/upgrade_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"url": {"type": "string"},
|
||||
"image": {"type": "string"},
|
||||
"rollback": {"type": "string"},
|
||||
"policy": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"url": {"type": "string"},
|
||||
"image": {"type": "string"},
|
||||
"rollback": {"type": "string"}
|
||||
}
|
||||
},
|
||||
|
||||
"docker_config": {
|
||||
"id": "#/definitions/docker_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"docker_config": {
|
||||
"id": "#/definitions/docker_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"engine": {"type": "string"},
|
||||
"tls": {"type": "boolean"},
|
||||
"tls_args": {"$ref": "#/definitions/list_of_strings"},
|
||||
"args": {"$ref": "#/definitions/list_of_strings"},
|
||||
"extra_args": {"$ref": "#/definitions/list_of_strings"},
|
||||
"server_cert": {"type": "string"},
|
||||
"server_key": {"type": "string"},
|
||||
"ca_cert": {"type": "string"},
|
||||
"ca_key": {"type": "string"},
|
||||
"environment": {"$ref": "#/definitions/list_of_strings"},
|
||||
"storage_context": {"type": "string"},
|
||||
"exec": {"type": ["boolean", "null"]},
|
||||
"bridge": {"type": "string"},
|
||||
"bip": {"type": "string"},
|
||||
"config_file": {"type": "string"},
|
||||
"containerd": {"type": "string"},
|
||||
"debug": {"type": ["boolean", "null"]},
|
||||
"exec_root": {"type": "string"},
|
||||
"group": {"type": "string"},
|
||||
"graph": {"type": "string"},
|
||||
"host": {"type": "array"},
|
||||
"live_restore": {"type": ["boolean", "null"]},
|
||||
"log_driver": {"type": "string"},
|
||||
"log_opts": {"type": "object"},
|
||||
"pid_file": {"type": "string"},
|
||||
"registry_mirror": {"type": "string"},
|
||||
"restart": {"type": ["boolean", "null"]},
|
||||
"selinux_enabled": {"type": ["boolean", "null"]},
|
||||
"storage_driver": {"type": "string"},
|
||||
"userland_proxy": {"type": ["boolean", "null"]},
|
||||
"insecure_registry": {"$ref": "#/definitions/list_of_strings"}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"engine": {"type": "string"},
|
||||
"tls": {"type": "boolean"},
|
||||
"tls_args": {"$ref": "#/definitions/list_of_strings"},
|
||||
"args": {"$ref": "#/definitions/list_of_strings"},
|
||||
"extra_args": {"$ref": "#/definitions/list_of_strings"},
|
||||
"server_cert": {"type": "string"},
|
||||
"server_key": {"type": "string"},
|
||||
"ca_cert": {"type": "string"},
|
||||
"ca_key": {"type": "string"},
|
||||
"environment": {"$ref": "#/definitions/list_of_strings"},
|
||||
"storage_context": {"type": "string"},
|
||||
"exec": {"type": ["boolean", "null"]},
|
||||
"bridge": {"type": "string"},
|
||||
"bip": {"type": "string"},
|
||||
"config_file": {"type": "string"},
|
||||
"containerd": {"type": "string"},
|
||||
"debug": {"type": ["boolean", "null"]},
|
||||
"exec_root": {"type": "string"},
|
||||
"group": {"type": "string"},
|
||||
"graph": {"type": "string"},
|
||||
"host": {"type": "array"},
|
||||
"live_restore": {"type": ["boolean", "null"]},
|
||||
"log_driver": {"type": "string"},
|
||||
"log_opts": {"type": "object"},
|
||||
"pid_file": {"type": "string"},
|
||||
"registry_mirror": {"type": "string"},
|
||||
"restart": {"type": ["boolean", "null"]},
|
||||
"selinux_enabled": {"type": ["boolean", "null"]},
|
||||
"storage_driver": {"type": "string"},
|
||||
"userland_proxy": {"type": ["boolean", "null"]},
|
||||
"insecure_registry": {"$ref": "#/definitions/list_of_strings"}
|
||||
}
|
||||
},
|
||||
|
||||
"ssh_config": {
|
||||
"id": "#/definitions/ssh_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"ssh_config": {
|
||||
"id": "#/definitions/ssh_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"keys": {"type": "object"},
|
||||
"daemon": {"type": "boolean"},
|
||||
"port": {"type": "integer"},
|
||||
"listen_address": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"keys": {"type": "object"},
|
||||
"daemon": {"type": "boolean"},
|
||||
"port": {"type": "integer"},
|
||||
"listen_address": {"type": "string"}
|
||||
}
|
||||
},
|
||||
|
||||
"state_config": {
|
||||
"id": "#/definitions/state_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"state_config": {
|
||||
"id": "#/definitions/state_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"directory": {"type": "string"},
|
||||
"fstype": {"type": "string"},
|
||||
"dev": {"type": "string"},
|
||||
"wait": {"type": "boolean"},
|
||||
"required": {"type": "boolean"},
|
||||
"autoformat": {"$ref": "#/definitions/list_of_strings"},
|
||||
"mdadm_scan": {"type": "boolean"},
|
||||
"cryptsetup": {"type": "boolean"},
|
||||
"lvm_scan": {"type": "boolean"},
|
||||
"rngd": {"type": "boolean"},
|
||||
"script": {"type": "string"},
|
||||
"oem_fstype": {"type": "string"},
|
||||
"oem_dev": {"type": "string"},
|
||||
"boot_fstype": {"type": "string"},
|
||||
"boot_dev": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"directory": {"type": "string"},
|
||||
"fstype": {"type": "string"},
|
||||
"dev": {"type": "string"},
|
||||
"wait": {"type": "boolean"},
|
||||
"required": {"type": "boolean"},
|
||||
"autoformat": {"$ref": "#/definitions/list_of_strings"},
|
||||
"mdadm_scan": {"type": "boolean"},
|
||||
"script": {"type": "string"},
|
||||
"oem_fstype": {"type": "string"},
|
||||
"oem_dev": {"type": "string"}
|
||||
}
|
||||
},
|
||||
|
||||
"cloud_init_config": {
|
||||
"id": "#/definitions/cloud_init_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"cloud_init_config": {
|
||||
"id": "#/definitions/cloud_init_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"datasources": {"$ref": "#/definitions/list_of_strings"}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"datasources": {"$ref": "#/definitions/list_of_strings"}
|
||||
}
|
||||
},
|
||||
|
||||
"defaults_config": {
|
||||
"id": "#/definitions/defaults_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"defaults_config": {
|
||||
"id": "#/definitions/defaults_config",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"hostname": {"type": "string"},
|
||||
"docker": {"type": "object"},
|
||||
"network": {"$ref": "#/definitions/network_config"},
|
||||
"system_docker_logs": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"hostname": {"type": "string"},
|
||||
"docker": {"type": "object"},
|
||||
"network": {"$ref": "#/definitions/network_config"}
|
||||
}
|
||||
},
|
||||
|
||||
"list_of_strings": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"uniqueItems": true
|
||||
}
|
||||
}
|
||||
"list_of_strings": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"uniqueItems": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
`
|
||||
|
||||
@@ -4,40 +4,38 @@ import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/rancher/os/config/cloudinit/config"
|
||||
"github.com/rancher/os/config/yaml"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
|
||||
"github.com/docker/engine-api/types"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/rancher/os/config/cloudinit/config"
|
||||
"github.com/rancher/os/config/yaml"
|
||||
"github.com/rancher/os/netconf"
|
||||
)
|
||||
|
||||
const (
|
||||
OemDir = "/usr/share/ros/oem"
|
||||
BootDir = "/boot"
|
||||
StateDir = "/state"
|
||||
OEM = "/usr/share/ros/oem"
|
||||
DockerBin = "/usr/bin/docker"
|
||||
DockerDistBin = "/usr/bin/docker.dist"
|
||||
RosBin = "/usr/bin/ros"
|
||||
SysInitBin = "/usr/bin/ros-sysinit"
|
||||
SystemDockerHome = "/var/lib/system-docker"
|
||||
SystemDockerHost = "unix:///var/run/system-docker.sock"
|
||||
DockerHost = "unix:///var/run/docker.sock"
|
||||
ImagesPath = "/usr/share/ros"
|
||||
InitImages = "images-init.tar"
|
||||
SystemImages = "images-system.tar"
|
||||
UserImages = "images-user.tar"
|
||||
ImagesPattern = "images*.tar"
|
||||
ModulesArchive = "/modules.tar"
|
||||
Debug = false
|
||||
SystemDockerLog = "/var/log/system-docker.log"
|
||||
SystemDockerBin = "/usr/bin/system-dockerd"
|
||||
DefaultDind = "rancher/os-dind:17.12.1"
|
||||
|
||||
DetachLabel = "io.rancher.os.detach"
|
||||
CreateOnlyLabel = "io.rancher.os.createonly"
|
||||
ReloadConfigLabel = "io.rancher.os.reloadconfig"
|
||||
ConsoleLabel = "io.rancher.os.console"
|
||||
ScopeLabel = "io.rancher.os.scope"
|
||||
RebuildLabel = "io.docker.compose.rebuild"
|
||||
UserDockerLabel = "io.rancher.user_docker.name"
|
||||
UserDockerNetLabel = "io.rancher.user_docker.net"
|
||||
UserDockerFIPLabel = "io.rancher.user_docker.fix_ip"
|
||||
System = "system"
|
||||
HashLabel = "io.rancher.os.hash"
|
||||
IDLabel = "io.rancher.os.id"
|
||||
DetachLabel = "io.rancher.os.detach"
|
||||
CreateOnlyLabel = "io.rancher.os.createonly"
|
||||
ReloadConfigLabel = "io.rancher.os.reloadconfig"
|
||||
ConsoleLabel = "io.rancher.os.console"
|
||||
ScopeLabel = "io.rancher.os.scope"
|
||||
RebuildLabel = "io.docker.compose.rebuild"
|
||||
System = "system"
|
||||
|
||||
OsConfigFile = "/usr/share/ros/os-config.yml"
|
||||
VarRancherDir = "/var/lib/rancher"
|
||||
@@ -49,18 +47,10 @@ const (
|
||||
MetaDataFile = "/var/lib/rancher/conf/metadata"
|
||||
CloudConfigFile = "/var/lib/rancher/conf/cloud-config.yml"
|
||||
EtcResolvConfFile = "/etc/resolv.conf"
|
||||
WPAConfigFile = "/etc/wpa_supplicant-%s.conf"
|
||||
WPATemplateFile = "/etc/wpa_supplicant.conf.tpl"
|
||||
DHCPCDConfigFile = "/etc/dhcpcd.conf"
|
||||
DHCPCDTemplateFile = "/etc/dhcpcd.conf.tpl"
|
||||
MultiDockerConfFile = "/var/lib/rancher/conf.d/m-user-docker.yml"
|
||||
MultiDockerDataDir = "/var/lib/m-user-docker"
|
||||
UdevRulesDir = "/etc/udev/rules.d"
|
||||
UdevRulesExtrasDir = "/lib/udev/rules-extras.d"
|
||||
)
|
||||
|
||||
var (
|
||||
OemConfigFile = OemDir + "/oem-config.yml"
|
||||
OemConfigFile = OEM + "/oem-config.yml"
|
||||
Version string
|
||||
BuildDate string
|
||||
Arch string
|
||||
@@ -79,10 +69,6 @@ var (
|
||||
"rancher.autologin",
|
||||
"EXTRA_CMDLINE",
|
||||
}
|
||||
SupportedDinds = []string{
|
||||
"rancher/os-dind:17.12.1",
|
||||
"rancher/os-dind:18.03.1",
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -139,6 +125,7 @@ type RancherConfig struct {
|
||||
ServicesInclude map[string]bool `yaml:"services_include,omitempty"`
|
||||
Modules []string `yaml:"modules,omitempty"`
|
||||
Network netconf.NetworkConfig `yaml:"network,omitempty"`
|
||||
DefaultNetwork netconf.NetworkConfig `yaml:"default_network,omitempty"`
|
||||
Repositories Repositories `yaml:"repositories,omitempty"`
|
||||
SSH SSHConfig `yaml:"ssh,omitempty"`
|
||||
State StateConfig `yaml:"state,omitempty"`
|
||||
@@ -152,7 +139,6 @@ type RancherConfig struct {
|
||||
RestartServices []string `yaml:"restart_services,omitempty"`
|
||||
HypervisorService bool `yaml:"hypervisor_service,omitempty"`
|
||||
ShutdownTimeout int `yaml:"shutdown_timeout,omitempty"`
|
||||
HTTPLoadRetries int `yaml:"http_load_retries,omitempty"`
|
||||
PreloadWait bool `yaml:"preload_wait,omitempty"`
|
||||
}
|
||||
|
||||
@@ -160,7 +146,6 @@ type UpgradeConfig struct {
|
||||
URL string `yaml:"url,omitempty"`
|
||||
Image string `yaml:"image,omitempty"`
|
||||
Rollback string `yaml:"rollback,omitempty"`
|
||||
Policy string `yaml:"policy,omitempty"`
|
||||
}
|
||||
|
||||
type EngineOpts struct {
|
||||
@@ -215,14 +200,9 @@ type StateConfig struct {
|
||||
Required bool `yaml:"required,omitempty"`
|
||||
Autoformat []string `yaml:"autoformat,omitempty"`
|
||||
MdadmScan bool `yaml:"mdadm_scan,omitempty"`
|
||||
LvmScan bool `yaml:"lvm_scan,omitempty"`
|
||||
Cryptsetup bool `yaml:"cryptsetup,omitempty"`
|
||||
Rngd bool `yaml:"rngd,omitempty"`
|
||||
Script string `yaml:"script,omitempty"`
|
||||
OemFsType string `yaml:"oem_fstype,omitempty"`
|
||||
OemDev string `yaml:"oem_dev,omitempty"`
|
||||
BootFsType string `yaml:"boot_fstype,omitempty"`
|
||||
BootDev string `yaml:"boot_dev,omitempty"`
|
||||
}
|
||||
|
||||
type CloudInit struct {
|
||||
@@ -230,10 +210,9 @@ type CloudInit struct {
|
||||
}
|
||||
|
||||
type Defaults struct {
|
||||
Hostname string `yaml:"hostname,omitempty"`
|
||||
Docker DockerConfig `yaml:"docker,omitempty"`
|
||||
Network netconf.NetworkConfig `yaml:"network,omitempty"`
|
||||
SystemDockerLogs string `yaml:"system_docker_logs,omitempty"`
|
||||
Hostname string `yaml:"hostname,omitempty"`
|
||||
Docker DockerConfig `yaml:"docker,omitempty"`
|
||||
Network netconf.NetworkConfig `yaml:"network,omitempty"`
|
||||
}
|
||||
|
||||
func (r Repositories) ToArray() []string {
|
||||
|
||||
@@ -5,9 +5,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
func testValidate(t *testing.T, cfg []byte, contains string) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// +build linux
|
||||
|
||||
package one
|
||||
package dfs
|
||||
|
||||
import (
|
||||
"os"
|
||||
@@ -11,14 +11,11 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/rancher/os/config/cmdline"
|
||||
"github.com/rancher/os/pkg/init/one"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/netconf"
|
||||
"github.com/rancher/os/pkg/selinux"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
"github.com/docker/libnetwork/resolvconf"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/netconf"
|
||||
"github.com/rancher/os/selinux"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -208,7 +205,7 @@ func execDocker(config *Config, docker, cmd string, args []string) (*exec.Cmd, e
|
||||
return cmd, err
|
||||
}
|
||||
if config.PidOne {
|
||||
one.PidOne()
|
||||
PidOne()
|
||||
}
|
||||
return cmd, err
|
||||
}
|
||||
@@ -549,21 +546,11 @@ func createLayout(config *Config) error {
|
||||
|
||||
selinux.SetFileContext(graphDirectory, "system_u:object_r:var_lib_t:s0")
|
||||
|
||||
symlinks := [][]string{
|
||||
return CreateSymlinks([][]string{
|
||||
{"usr/lib", "/lib"},
|
||||
{"usr/sbin", "/sbin"},
|
||||
{"../run", "/var/run"},
|
||||
}
|
||||
|
||||
rootCmdline := cmdline.GetCmdline("root")
|
||||
rootDevice := rootCmdline.(string)
|
||||
if rootDevice != "" {
|
||||
if _, err := os.Stat("/dev/root"); os.IsNotExist(err) {
|
||||
symlinks = append(symlinks, []string{rootDevice, "/dev/root"})
|
||||
}
|
||||
}
|
||||
|
||||
return CreateSymlinks(symlinks)
|
||||
})
|
||||
}
|
||||
|
||||
func firstPrepare() error {
|
||||
@@ -5,12 +5,11 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
"github.com/docker/docker/registry"
|
||||
"github.com/docker/engine-api/types"
|
||||
"github.com/docker/libcompose/docker"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
// ConfigAuthLookup will lookup registry auth info from cloud config
|
||||
@@ -1,9 +1,8 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"github.com/rancher/os/config"
|
||||
|
||||
dockerClient "github.com/docker/engine-api/client"
|
||||
"github.com/rancher/os/config"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
@@ -4,14 +4,14 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
dockerclient "github.com/docker/engine-api/client"
|
||||
composeClient "github.com/docker/libcompose/docker/client"
|
||||
"github.com/docker/libcompose/project"
|
||||
"golang.org/x/net/context"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/log"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
type ClientFactory struct {
|
||||
@@ -4,10 +4,9 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
type ConfigEnvironment struct {
|
||||
@@ -2,19 +2,15 @@ package docker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util/network"
|
||||
|
||||
"github.com/docker/docker/layer"
|
||||
dockerclient "github.com/docker/engine-api/client"
|
||||
"github.com/docker/engine-api/types"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/docker"
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/docker/libcompose/project/options"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/log"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
@@ -58,28 +54,10 @@ func (s *Service) missingImage() bool {
|
||||
return false
|
||||
}
|
||||
client := s.context.ClientFactory.Create(s)
|
||||
|
||||
// If it is already built-in, we should use tag image
|
||||
// use case: open-vmtools with another REGISTRY_DOMAIN setting
|
||||
registryDomain := config.LoadConfig().Rancher.Environment["REGISTRY_DOMAIN"]
|
||||
if registryDomain != "docker.io" && strings.Index(image, registryDomain) >= 0 {
|
||||
orginImage := strings.SplitN(image, "/", 2)[1]
|
||||
_, _, err := client.ImageInspectWithRaw(context.Background(), orginImage, false)
|
||||
if err == nil {
|
||||
log.Infof("Will tag image %s to %s", orginImage, image)
|
||||
options := types.ImageTagOptions{
|
||||
ImageID: orginImage,
|
||||
RepositoryName: strings.SplitN(image, ":", 2)[0],
|
||||
Tag: strings.SplitN(image, ":", 2)[1],
|
||||
Force: false,
|
||||
}
|
||||
if err := client.ImageTag(context.Background(), options); err != nil {
|
||||
log.Warnf("Failed to tag image from %s to %s: %v", orginImage, image, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, _, err := client.ImageInspectWithRaw(context.Background(), image, false)
|
||||
if err != nil {
|
||||
log.Errorf("Missing the image: %v", err)
|
||||
}
|
||||
return err != nil
|
||||
}
|
||||
|
||||
@@ -156,13 +134,6 @@ func (s *Service) shouldRebuild(ctx context.Context) (bool, error) {
|
||||
func (s *Service) Up(ctx context.Context, options options.Up) error {
|
||||
labels := s.Config().Labels
|
||||
|
||||
// wait for networking if necessary
|
||||
if after := labels["io.rancher.os.after"]; after == "network" {
|
||||
if err := network.AllDefaultGWOK(network.DefaultRoutesCheckTimeout); err != nil {
|
||||
log.Warnf("Timeout to wait for the networking ready: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Service.Create(ctx, options.Create); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -179,13 +150,7 @@ func (s *Service) Up(ctx context.Context, options options.Up) error {
|
||||
}
|
||||
for _, c := range cs {
|
||||
if _, err := c.(*docker.Container).Recreate(ctx, s.Config().Image); err != nil {
|
||||
// sometimes we can get ErrMountNameConflict when booting on RPi
|
||||
// ignore this error so that ros can boot success, otherwise it will hang forever
|
||||
if strings.Contains(err.Error(), layer.ErrMountNameConflict.Error()) {
|
||||
log.Warn(err)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err = s.rename(ctx); err != nil {
|
||||
@@ -1,11 +1,10 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/docker"
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
type ServiceFactory struct {
|
||||
@@ -1,9 +1,8 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"github.com/rancher/os/config"
|
||||
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
"github.com/rancher/os/config"
|
||||
)
|
||||
|
||||
func IsSystemContainer(serviceConfig *composeConfig.ServiceConfig) bool {
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user