Compare commits

..

8 Commits

Author SHA1 Message Date
niusmallnan
72eff0bf5e Bump kernel to v4.14.65 2018-08-22 17:46:11 +08:00
stffabi
39e97a6754 Decompress user-data if it is gzipped
Fixes #2391

(cherry picked from commit 05c2a40aa5)
2018-08-21 13:37:34 +08:00
niusmallnan
e4653b55c1 Clean cni dir
(cherry picked from commit 5e4f63f02e)
2018-08-21 13:37:34 +08:00
niusmallnan
0b0cd67150 Change SYSTEM_DOCKER from niusmallnan/os-system-docker to rancher/os-system-docker
(cherry picked from commit 6e0952d69e)
2018-08-21 13:37:34 +08:00
niusmallnan
b4aa06aced Bump kernel to 4.14.32-rancher3
This kernel contains objtool, which is a key to compiling third-party modules.
2018-08-21 13:37:34 +08:00
niusmallnan
d513c3beca Make sure that DOCKER_RAMDISK can be set correctly because we changed the user-docker directory
(cherry picked from commit 9d3dd8796e)
2018-08-21 13:37:34 +08:00
Jason-ZW
06b54536cf Add systemd cgroup directory
(cherry picked from commit f6ebb5002e)
2018-08-21 13:37:34 +08:00
niusmallnan
b1d3274bce Fix the missing of CloudConfigScriptFile
(cherry picked from commit b6629d44fb)
2018-08-21 13:37:34 +08:00
1166 changed files with 131193 additions and 9100 deletions

View File

@@ -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
View File

@@ -17,6 +17,5 @@
__pycache__
/.dapper
/.trash-cache
/trash.lock
.idea
.trash-conf

View File

@@ -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 && \

View File

@@ -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
View File

@@ -1,9 +1,5 @@
# RancherOS
[![Build Status](https://drone-pr.rancher.io/api/badges/rancher/os/status.svg?branch=master)](https://drone-pr.rancher.io/rancher/os)
[![Docker Pulls](https://img.shields.io/docker/pulls/rancher/os.svg)](https://store.docker.com/community/images/rancher/os)
[![Go Report Card](https://goreportcard.com/badge/github.com/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.

View File

@@ -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 (

View File

@@ -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

View File

@@ -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)

View File

@@ -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() {

View File

@@ -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 {

View File

@@ -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() {

View File

@@ -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)
}

View File

@@ -2,11 +2,11 @@ package control
import (
"bytes"
"os"
"strings"
"testing"
"github.com/stretchr/testify/require"
"os"
)
func TestGenTpl(t *testing.T) {

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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",

View File

@@ -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)
}

View File

@@ -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 (

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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"
}

View File

@@ -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
}

View File

@@ -9,7 +9,7 @@ import (
"path/filepath"
"strings"
"github.com/rancher/os/pkg/log"
"github.com/rancher/os/log"
)
func syslinuxConfig(menu BootVars) error {

View File

@@ -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 == "" {

View File

@@ -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

View File

@@ -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 {

View File

@@ -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",

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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

View File

@@ -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 (

View File

@@ -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 {

View File

@@ -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
}
}

View File

@@ -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
}

View File

@@ -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()
}

View File

@@ -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()
}
}
}

View File

@@ -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
}

View File

@@ -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 (

View File

@@ -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 {

View File

@@ -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)
}
}

View File

@@ -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() {

View File

@@ -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)
}

View File

@@ -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{}{}

View File

@@ -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...]
```

View File

@@ -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, "-") {

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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 (

View File

@@ -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
}

View File

@@ -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 ""
}

View File

@@ -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 (

View 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 (

View 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) {

View File

@@ -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

View File

@@ -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) {

View File

@@ -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"
}

View File

@@ -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 ""
}

View File

@@ -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 {

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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)
}

View File

@@ -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)
}
}
}

View File

@@ -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"
}

View File

@@ -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())
}
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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
}

View File

@@ -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)

View 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
}

View 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)
}
}
}

View File

@@ -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)
}
}
}

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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)
}

View File

@@ -1,6 +1,6 @@
#!/bin/bash -e
source build
source ./build
SRC=$(find . -name '*.go' \
-not -path "./vendor/*")

View File

@@ -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.") {

View File

@@ -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 = `

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
}
}
}
`

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -1,6 +1,6 @@
// +build linux
package one
package dfs
import (
"os"

View File

@@ -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 {

View File

@@ -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

View File

@@ -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"
)

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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