Compare commits
35 Commits
v1.5.4-rc1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcdc9ca432 | ||
|
|
719722a466 | ||
|
|
628e6ab052 | ||
|
|
4b9e8ac145 | ||
|
|
b3d0b298c5 | ||
|
|
93431c9dbd | ||
|
|
2ec7f4fc9e | ||
|
|
a58d390ea5 | ||
|
|
2ed9befdf2 | ||
|
|
397977b0af | ||
|
|
7c84c5f7e4 | ||
|
|
5b629d0d13 | ||
|
|
6c9be2625e | ||
|
|
7b8c79bbdf | ||
|
|
71623750fc | ||
|
|
67599f352c | ||
|
|
8ad6b10446 | ||
|
|
27d4dd2b8b | ||
|
|
23cc740eae | ||
|
|
29aaadd88c | ||
|
|
88c5b5ef14 | ||
|
|
615a6e4415 | ||
|
|
4a2744e858 | ||
|
|
ebc170def6 | ||
|
|
ce9d497890 | ||
|
|
869559924b | ||
|
|
6a840ff5c8 | ||
|
|
bfa2592538 | ||
|
|
8edb916513 | ||
|
|
7cad727413 | ||
|
|
3fac5f7604 | ||
|
|
a8cf965b2a | ||
|
|
4841467d41 | ||
|
|
3961aa6855 | ||
|
|
1893c7863b |
@@ -60,7 +60,7 @@ ARG DISTRIB_ID=RancherOS
|
||||
|
||||
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_VERSION=4.14.176-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
|
||||
|
||||
@@ -85,8 +85,8 @@ ARG SYSTEM_DOCKER_VERSION=17.06-ros6
|
||||
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=18.09.8
|
||||
ARG USER_DOCKER_ENGINE_VERSION=docker-${USER_DOCKER_VERSION}-ce
|
||||
ARG USER_DOCKER_VERSION=19.03.8
|
||||
ARG USER_DOCKER_ENGINE_VERSION=docker-${USER_DOCKER_VERSION}
|
||||
|
||||
ARG AZURE_SERVICE=false
|
||||
ARG PROXMOXVE_SERVICE=false
|
||||
|
||||
2
Makefile
2
Makefile
@@ -48,7 +48,7 @@ rpi64: .dapper
|
||||
|
||||
vmware: .dapper
|
||||
mkdir -p dist
|
||||
APPEND_SYSTEM_IMAGES="rancher/os-openvmtools:10.3.10-1" \
|
||||
APPEND_SYSTEM_IMAGES="rancher/os-openvmtools:10.3.10-2" \
|
||||
./.dapper release-vmware
|
||||
|
||||
hyperv: .dapper
|
||||
|
||||
96
README.md
96
README.md
@@ -18,68 +18,68 @@ it would really be bad if somebody did `docker rm -f $(docker ps -qa)` and delet
|
||||
|
||||
## Release
|
||||
|
||||
- **v1.5.3 - Docker 18.06.3-ce - Linux 4.14.128**
|
||||
- **v1.5.8 - Docker 19.03.15 - Linux 4.14.138**
|
||||
|
||||
### ISO
|
||||
|
||||
- https://releases.rancher.com/os/v1.5.3/rancheros.iso
|
||||
- https://releases.rancher.com/os/v1.5.3/hyperv/rancheros.iso
|
||||
- https://releases.rancher.com/os/v1.5.3/4glte/rancheros.iso
|
||||
- https://releases.rancher.com/os/v1.5.3/vmware/rancheros.iso
|
||||
- https://releases.rancher.com/os/v1.5.8/rancheros.iso
|
||||
- https://releases.rancher.com/os/v1.5.8/hyperv/rancheros.iso
|
||||
- https://releases.rancher.com/os/v1.5.8/4glte/rancheros.iso
|
||||
- https://releases.rancher.com/os/v1.5.8/vmware/rancheros.iso
|
||||
|
||||
#### Special docker-machine Links
|
||||
|
||||
- https://releases.rancher.com/os/v1.5.3/vmware/rancheros-autoformat.iso
|
||||
- https://releases.rancher.com/os/v1.5.3/proxmoxve/rancheros-autoformat.iso
|
||||
- https://releases.rancher.com/os/v1.5.8/vmware/rancheros-autoformat.iso
|
||||
- https://releases.rancher.com/os/v1.5.8/proxmoxve/rancheros-autoformat.iso
|
||||
|
||||
### Additional Downloads
|
||||
|
||||
#### AMD64 Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.3/initrd
|
||||
* https://releases.rancher.com/os/v1.5.3/vmlinuz
|
||||
* https://releases.rancher.com/os/v1.5.3/rancheros.ipxe
|
||||
* https://releases.rancher.com/os/v1.5.3/rootfs.tar.gz
|
||||
* https://releases.rancher.com/os/v1.5.8/initrd
|
||||
* https://releases.rancher.com/os/v1.5.8/vmlinuz
|
||||
* https://releases.rancher.com/os/v1.5.8/rancheros.ipxe
|
||||
* https://releases.rancher.com/os/v1.5.8/rootfs.tar.gz
|
||||
|
||||
#### ARM64 Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.3/arm64/initrd
|
||||
* https://releases.rancher.com/os/v1.5.3/arm64/vmlinuz
|
||||
* https://releases.rancher.com/os/v1.5.3/arm64/rootfs_arm64.tar.gz
|
||||
* https://releases.rancher.com/os/v1.5.3/arm64/rancheros-raspberry-pi64.zip
|
||||
* https://releases.rancher.com/os/v1.5.8/arm64/initrd
|
||||
* https://releases.rancher.com/os/v1.5.8/arm64/vmlinuz
|
||||
* https://releases.rancher.com/os/v1.5.8/arm64/rootfs_arm64.tar.gz
|
||||
* https://releases.rancher.com/os/v1.5.8/arm64/rancheros-raspberry-pi64.zip
|
||||
|
||||
#### Cloud Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.3/rancheros-openstack.img
|
||||
* https://releases.rancher.com/os/v1.5.3/rancheros-digitalocean.img
|
||||
* https://releases.rancher.com/os/v1.5.3/rancheros-cloudstack.img
|
||||
* https://releases.rancher.com/os/v1.5.3/rancheros-aliyun.vhd
|
||||
* https://releases.rancher.com/os/v1.5.3/rancheros-gce.tar.gz
|
||||
* https://releases.rancher.com/os/v1.5.8/rancheros-openstack.img
|
||||
* https://releases.rancher.com/os/v1.5.8/rancheros-digitalocean.img
|
||||
* https://releases.rancher.com/os/v1.5.8/rancheros-cloudstack.img
|
||||
* https://releases.rancher.com/os/v1.5.8/rancheros-aliyun.vhd
|
||||
* https://releases.rancher.com/os/v1.5.8/rancheros-gce.tar.gz
|
||||
|
||||
#### VMware Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.3/vmware/initrd
|
||||
* https://releases.rancher.com/os/v1.5.3/vmware/rancheros.vmdk
|
||||
* https://releases.rancher.com/os/v1.5.3/vmware/rootfs.tar.gz
|
||||
* https://releases.rancher.com/os/v1.5.8/vmware/initrd
|
||||
* https://releases.rancher.com/os/v1.5.8/vmware/rancheros.vmdk
|
||||
* https://releases.rancher.com/os/v1.5.8/vmware/rootfs.tar.gz
|
||||
|
||||
#### Hyper-V Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.3/hyperv/initrd
|
||||
* https://releases.rancher.com/os/v1.5.3/hyperv/rootfs.tar.gz
|
||||
* https://releases.rancher.com/os/v1.5.8/hyperv/initrd
|
||||
* https://releases.rancher.com/os/v1.5.8/hyperv/rootfs.tar.gz
|
||||
|
||||
#### Proxmox VE Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.3/proxmoxve/initrd
|
||||
* https://releases.rancher.com/os/v1.5.3/proxmoxve/rootfs.tar.gz
|
||||
* https://releases.rancher.com/os/v1.5.8/proxmoxve/initrd
|
||||
* https://releases.rancher.com/os/v1.5.8/proxmoxve/rootfs.tar.gz
|
||||
|
||||
#### 4G-LTE Links
|
||||
|
||||
* https://releases.rancher.com/os/v1.5.3/4glte/initrd
|
||||
* https://releases.rancher.com/os/v1.5.3/4glte/rootfs.tar.gz
|
||||
* https://releases.rancher.com/os/v1.5.8/4glte/initrd
|
||||
* https://releases.rancher.com/os/v1.5.8/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.3` in the above URLs if you want to get the latest version.
|
||||
2. you can use `latest` instead of `v1.5.8` in the above URLs if you want to get the latest version.
|
||||
|
||||
### Amazon
|
||||
|
||||
@@ -89,24 +89,22 @@ SSH keys are added to the **`rancher`** user, so you must log in using the **ran
|
||||
|
||||
Region | Type | AMI
|
||||
-------|------|------
|
||||
eu-north-1 | HVM | [ami-0d0ee5e9b88ab3641](https://eu-north-1.console.aws.amazon.com/ec2/home?region=eu-north-1#launchInstanceWizard:ami=ami-0d0ee5e9b88ab3641)
|
||||
ap-south-1 | HVM | [ami-0e64d18d3546bc0e3](https://ap-south-1.console.aws.amazon.com/ec2/home?region=ap-south-1#launchInstanceWizard:ami=ami-0e64d18d3546bc0e3)
|
||||
eu-west-3 | HVM | [ami-0f1cfb7093ca6f8c6](https://eu-west-3.console.aws.amazon.com/ec2/home?region=eu-west-3#launchInstanceWizard:ami=ami-0f1cfb7093ca6f8c6)
|
||||
eu-west-2 | HVM | [ami-0fb2092ee913a1deb](https://eu-west-2.console.aws.amazon.com/ec2/home?region=eu-west-2#launchInstanceWizard:ami=ami-0fb2092ee913a1deb)
|
||||
eu-west-1 | HVM | [ami-01bcb29c6aebb24bb](https://eu-west-1.console.aws.amazon.com/ec2/home?region=eu-west-1#launchInstanceWizard:ami=ami-01bcb29c6aebb24bb)
|
||||
ap-northeast-2 | HVM | [ami-0c52edead8ffab5d0](https://ap-northeast-2.console.aws.amazon.com/ec2/home?region=ap-northeast-2#launchInstanceWizard:ami=ami-0c52edead8ffab5d0)
|
||||
ap-northeast-1 | HVM | [ami-0b6f89180ebf76c13](https://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#launchInstanceWizard:ami=ami-0b6f89180ebf76c13)
|
||||
sa-east-1 | HVM | [ami-04ab75c51a5fc9be6](https://sa-east-1.console.aws.amazon.com/ec2/home?region=sa-east-1#launchInstanceWizard:ami=ami-04ab75c51a5fc9be6)
|
||||
ca-central-1 | HVM | [ami-0dd7a2d93147d7eff](https://ca-central-1.console.aws.amazon.com/ec2/home?region=ca-central-1#launchInstanceWizard:ami=ami-0dd7a2d93147d7eff)
|
||||
ap-southeast-1 | HVM | [ami-058ff3e97841ed000](https://ap-southeast-1.console.aws.amazon.com/ec2/home?region=ap-southeast-1#launchInstanceWizard:ami=ami-058ff3e97841ed000)
|
||||
ap-southeast-2 | HVM | [ami-07bc506efd2ade5f1](https://ap-southeast-2.console.aws.amazon.com/ec2/home?region=ap-southeast-2#launchInstanceWizard:ami=ami-07bc506efd2ade5f1)
|
||||
eu-central-1 | HVM | [ami-0143355d2c9ff8db5](https://eu-central-1.console.aws.amazon.com/ec2/home?region=eu-central-1#launchInstanceWizard:ami=ami-0143355d2c9ff8db5)
|
||||
us-east-1 | HVM | [ami-0a48e384fc0262754](https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#launchInstanceWizard:ami=ami-0a48e384fc0262754)
|
||||
us-east-2 | HVM | [ami-03cc2d26e5ad831ea](https://us-east-2.console.aws.amazon.com/ec2/home?region=us-east-2#launchInstanceWizard:ami=ami-03cc2d26e5ad831ea)
|
||||
us-west-1 | HVM | [ami-0d1728efec5c95f06](https://us-west-1.console.aws.amazon.com/ec2/home?region=us-west-1#launchInstanceWizard:ami=ami-0d1728efec5c95f06)
|
||||
us-west-2 | HVM | [ami-0d5f95b9a27dfef6f](https://us-west-2.console.aws.amazon.com/ec2/home?region=us-west-2#launchInstanceWizard:ami=ami-0d5f95b9a27dfef6f)
|
||||
cn-north-1 | HVM | [ami-08e1d5d0aa44a7606](https://cn-north-1.console.amazonaws.cn/ec2/home?region=cn-north-1#launchInstanceWizard:ami=ami-08e1d5d0aa44a7606)
|
||||
cn-northwest-1 | HVM | [ami-0847a5ca9e1b24751](https://cn-northwest-1.console.amazonaws.cn/ec2/home?region=cn-northwest-1#launchInstanceWizard:ami=ami-0847a5ca9e1b24751)
|
||||
eu-north-1 | HVM | [ami-08b189555c5d2d8c3](https://eu-north-1.console.aws.amazon.com/ec2/home?region=eu-north-1#launchInstanceWizard:ami=ami-08b189555c5d2d8c3)
|
||||
ap-south-1 | HVM | [ami-0086964cb1ffc4fdb](https://ap-south-1.console.aws.amazon.com/ec2/home?region=ap-south-1#launchInstanceWizard:ami=ami-0086964cb1ffc4fdb)
|
||||
eu-west-3 | HVM | [ami-088930cafc1ad9f20](https://eu-west-3.console.aws.amazon.com/ec2/home?region=eu-west-3#launchInstanceWizard:ami=ami-088930cafc1ad9f20)
|
||||
eu-west-2 | HVM | [ami-0fdf07cfd187af004](https://eu-west-2.console.aws.amazon.com/ec2/home?region=eu-west-2#launchInstanceWizard:ami=ami-0fdf07cfd187af004)
|
||||
eu-west-1 | HVM | [ami-0cea454c576ececbd](https://eu-west-1.console.aws.amazon.com/ec2/home?region=eu-west-1#launchInstanceWizard:ami=ami-0cea454c576ececbd)
|
||||
ap-northeast-2 | HVM | [ami-0fdb6555f88256d12](https://ap-northeast-2.console.aws.amazon.com/ec2/home?region=ap-northeast-2#launchInstanceWizard:ami=ami-0fdb6555f88256d12)
|
||||
ap-northeast-1 | HVM | [ami-052c75c3e8757bcd9](https://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#launchInstanceWizard:ami=ami-052c75c3e8757bcd9)
|
||||
sa-east-1 | HVM | [ami-04e51c9d1edad1bfd](https://sa-east-1.console.aws.amazon.com/ec2/home?region=sa-east-1#launchInstanceWizard:ami=ami-04e51c9d1edad1bfd)
|
||||
ca-central-1 | HVM | [ami-006a1ff3bf21003b3](https://ca-central-1.console.aws.amazon.com/ec2/home?region=ca-central-1#launchInstanceWizard:ami=ami-006a1ff3bf21003b3)
|
||||
ap-southeast-1 | HVM | [ami-03b14c67c74644c2b](https://ap-southeast-1.console.aws.amazon.com/ec2/home?region=ap-southeast-1#launchInstanceWizard:ami=ami-03b14c67c74644c2b)
|
||||
ap-southeast-2 | HVM | [ami-07059c8f12411bfcb](https://ap-southeast-2.console.aws.amazon.com/ec2/home?region=ap-southeast-2#launchInstanceWizard:ami=ami-07059c8f12411bfcb)
|
||||
eu-central-1 | HVM | [ami-0fc1a9332c246bc56](https://eu-central-1.console.aws.amazon.com/ec2/home?region=eu-central-1#launchInstanceWizard:ami=ami-0fc1a9332c246bc56)
|
||||
us-east-1 | HVM | [ami-02fe87f853d560d52](https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#launchInstanceWizard:ami=ami-02fe87f853d560d52)
|
||||
us-east-2 | HVM | [ami-004259f4c48585992](https://us-east-2.console.aws.amazon.com/ec2/home?region=us-east-2#launchInstanceWizard:ami=ami-004259f4c48585992)
|
||||
us-west-1 | HVM | [ami-0b382b76fadc95544](https://us-west-1.console.aws.amazon.com/ec2/home?region=us-west-1#launchInstanceWizard:ami=ami-0b382b76fadc95544)
|
||||
us-west-2 | HVM | [ami-0cdefa6a0646eb511](https://us-west-2.console.aws.amazon.com/ec2/home?region=us-west-2#launchInstanceWizard:ami=ami-0cdefa6a0646eb511)
|
||||
|
||||
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).
|
||||
|
||||
@@ -130,7 +128,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-2020 [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.
|
||||
|
||||
@@ -36,9 +36,11 @@ import (
|
||||
"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"
|
||||
@@ -228,7 +230,14 @@ func getDatasources(datasources []string) []datasource.Datasource {
|
||||
|
||||
switch parts[0] {
|
||||
case "*":
|
||||
dss = append(dss, getDatasources([]string{"configdrive", "vmware", "ec2", "digitalocean", "packet", "gce", "cloudstack"})...)
|
||||
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))
|
||||
case "cloudstack":
|
||||
for _, source := range cloudstack.NewDatasource(root) {
|
||||
dss = append(dss, source)
|
||||
|
||||
@@ -137,7 +137,7 @@ func consoleInitFunc() error {
|
||||
}
|
||||
}
|
||||
|
||||
baseSymlink := symLinkEngineBinary(cfg.Rancher.Docker.Engine)
|
||||
baseSymlink := symLinkEngineBinary()
|
||||
|
||||
if _, err := os.Stat(dockerCompletionFile); err == nil {
|
||||
baseSymlink = append(baseSymlink, symlink{
|
||||
|
||||
@@ -86,12 +86,13 @@ func dockerInitAction(c *cli.Context) error {
|
||||
}
|
||||
|
||||
cfg := config.LoadConfig()
|
||||
baseSymlink := symLinkEngineBinary(cfg.Rancher.Docker.Engine)
|
||||
|
||||
for _, link := range baseSymlink {
|
||||
for _, link := range symLinkEngineBinary() {
|
||||
syscall.Unlink(link.newname)
|
||||
if err := os.Symlink(link.oldname, link.newname); err != nil {
|
||||
log.Error(err)
|
||||
if _, err := os.Stat(link.oldname); err == nil {
|
||||
if err := os.Symlink(link.oldname, link.newname); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"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"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
"github.com/codegangsta/cli"
|
||||
@@ -364,8 +365,14 @@ func CurrentEngine() (engine string) {
|
||||
}
|
||||
if t, ok := image.(reference.NamedTagged); ok {
|
||||
tag := t.Tag()
|
||||
if !strings.HasPrefix(tag, "1.") {
|
||||
// TODO: this assumes we only do Docker ce :/
|
||||
|
||||
// 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>
|
||||
tag = tag + "-ce"
|
||||
}
|
||||
return "docker-" + tag
|
||||
|
||||
@@ -86,8 +86,8 @@ var installCommand = cli.Command{
|
||||
Usage: "reboot using kexec",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "stage, s",
|
||||
Usage: "stage services",
|
||||
Name: "save, s",
|
||||
Usage: "save services and images for next booting",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
@@ -179,13 +179,13 @@ func installAction(c *cli.Context) error {
|
||||
cloudConfig = uc
|
||||
}
|
||||
|
||||
stageImages := []string{}
|
||||
if c.Bool("stage") && cloudConfig != "" && installType != "upgrade" {
|
||||
stageImages = install.GetCacheImageList(cloudConfig, cfg)
|
||||
log.Debugf("Will cache these images: %s", stageImages)
|
||||
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, stageImages); err != nil {
|
||||
if err := runInstall(image, installType, cloudConfig, device, partition, statedir, kappend, force, kexec, isoinstallerloaded, debug, savedImages); err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Fatal("Failed to run install")
|
||||
return err
|
||||
}
|
||||
@@ -198,7 +198,7 @@ func installAction(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func runInstall(image, installType, cloudConfig, device, partition, statedir, kappend string, force, kexec, isoinstallerloaded, debug bool, stageImages []string) error {
|
||||
func runInstall(image, installType, cloudConfig, device, partition, statedir, kappend string, force, kexec, isoinstallerloaded, debug bool, savedImages []string) error {
|
||||
fmt.Printf("Installing from %s\n", image)
|
||||
|
||||
if !force {
|
||||
@@ -283,8 +283,8 @@ func runInstall(image, installType, cloudConfig, device, partition, statedir, ka
|
||||
if statedir != "" {
|
||||
installerCmd = append(installerCmd, "--statedir", statedir)
|
||||
}
|
||||
if len(stageImages) > 0 {
|
||||
installerCmd = append(installerCmd, "--stage")
|
||||
if len(savedImages) > 0 {
|
||||
installerCmd = append(installerCmd, "--save")
|
||||
}
|
||||
|
||||
// TODO: mount at /mnt for shared mount?
|
||||
@@ -348,8 +348,8 @@ func runInstall(image, installType, cloudConfig, device, partition, statedir, ka
|
||||
return err
|
||||
}
|
||||
|
||||
if len(stageImages) > 0 {
|
||||
return install.RunCacheScript(partition, stageImages)
|
||||
if len(savedImages) > 0 {
|
||||
return install.RunCacheScript(partition, savedImages)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -18,21 +18,21 @@ type ImageConfig struct {
|
||||
}
|
||||
|
||||
func GetCacheImageList(cloudconfig string, oldcfg *config.CloudConfig) []string {
|
||||
stageImages := make([]string, 0)
|
||||
savedImages := make([]string, 0)
|
||||
bytes, err := readConfigFile(cloudconfig)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Fatal("Failed to read cloud-config")
|
||||
return stageImages
|
||||
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 stageImages
|
||||
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 stageImages
|
||||
return savedImages
|
||||
}
|
||||
|
||||
// services_include
|
||||
@@ -40,7 +40,7 @@ func GetCacheImageList(cloudconfig string, oldcfg *config.CloudConfig) []string
|
||||
if value {
|
||||
serviceImage := getServiceImage(key, "", oldcfg, newcfg)
|
||||
if serviceImage != "" {
|
||||
stageImages = append(stageImages, serviceImage)
|
||||
savedImages = append(savedImages, serviceImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func GetCacheImageList(cloudconfig string, oldcfg *config.CloudConfig) []string
|
||||
if newConsole != "" && newConsole != "default" {
|
||||
consoleImage := getServiceImage(newConsole, "console", oldcfg, newcfg)
|
||||
if consoleImage != "" {
|
||||
stageImages = append(stageImages, consoleImage)
|
||||
savedImages = append(savedImages, consoleImage)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,12 +59,12 @@ func GetCacheImageList(cloudconfig string, oldcfg *config.CloudConfig) []string
|
||||
if newEngine != "" && newEngine != oldcfg.Rancher.Docker.Engine {
|
||||
engineImage := getServiceImage(newEngine, "docker", oldcfg, newcfg)
|
||||
if engineImage != "" {
|
||||
stageImages = append(stageImages, engineImage)
|
||||
savedImages = append(savedImages, engineImage)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return stageImages
|
||||
return savedImages
|
||||
}
|
||||
|
||||
func getServiceImage(service, svctype string, oldcfg, newcfg *config.CloudConfig) string {
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
"github.com/rancher/os/pkg/util/versions"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -34,30 +33,27 @@ func formatImage(image string, cfg *config.CloudConfig) string {
|
||||
return image
|
||||
}
|
||||
|
||||
func symLinkEngineBinary(version string) []symlink {
|
||||
versionNum := strings.Replace(strings.Replace(version, "docker-", "", -1), "-ce", "", -1)
|
||||
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"},
|
||||
{"/usr/share/ros/os-release", "/usr/lib/os-release"},
|
||||
{"/usr/share/ros/os-release", "/etc/os-release"},
|
||||
}
|
||||
if versions.GreaterThanOrEqualTo(versionNum, "18.09.0") {
|
||||
baseSymlink = append(baseSymlink, []symlink{
|
||||
{"/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"},
|
||||
}...)
|
||||
} else {
|
||||
baseSymlink = append(baseSymlink, []symlink{
|
||||
{"/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"},
|
||||
}...)
|
||||
|
||||
// >= 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
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ func shutdown(c *cli.Context) error {
|
||||
// cannot contain slashes.
|
||||
appName := filepath.Base(c.App.Name)
|
||||
if appName == "shutdown" && timeArg != "" {
|
||||
if timeArg != "now" {
|
||||
if timeArg != "now" && timeArg != "+0" {
|
||||
err := fmt.Errorf("Sorry, can't parse '%s' as time value (only 'now' supported)", timeArg)
|
||||
log.Error(err)
|
||||
return err
|
||||
|
||||
92
config/cloudinit/datasource/metadata/exoscale/metadata.go
Normal file
92
config/cloudinit/datasource/metadata/exoscale/metadata.go
Normal file
@@ -0,0 +1,92 @@
|
||||
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"
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
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 ""
|
||||
}
|
||||
114
config/cloudinit/datasource/proxmox/proxmox.go
Normal file
114
config/cloudinit/datasource/proxmox/proxmox.go
Normal file
@@ -0,0 +1,114 @@
|
||||
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)
|
||||
}
|
||||
77
config/cloudinit/datasource/proxmox/proxmox_test.go
Normal file
77
config/cloudinit/datasource/proxmox/proxmox_test.go
Normal file
@@ -0,0 +1,77 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,11 +18,12 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
neturl "net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/os/pkg/log"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -120,14 +121,14 @@ func (h *HTTPClient) GetRetry(rawurl string) ([]byte, error) {
|
||||
|
||||
duration := h.InitialBackoff
|
||||
for retry := 1; retry <= h.MaxRetries; retry++ {
|
||||
log.Printf("Fetching data from %s. Attempt #%d", dataURL, retry)
|
||||
log.Debugf("Fetching data from %s. Attempt #%d", dataURL, retry)
|
||||
|
||||
data, err := h.Get(dataURL)
|
||||
switch err.(type) {
|
||||
case ErrNetwork:
|
||||
log.Printf(err.Error())
|
||||
log.Debugf(err.Error())
|
||||
case ErrServer:
|
||||
log.Printf(err.Error())
|
||||
log.Debugf(err.Error())
|
||||
case ErrNotFound:
|
||||
return data, err
|
||||
default:
|
||||
@@ -135,7 +136,7 @@ func (h *HTTPClient) GetRetry(rawurl string) ([]byte, error) {
|
||||
}
|
||||
|
||||
duration = ExpBackoff(duration, h.MaxBackoff)
|
||||
log.Printf("Sleeping for %v...", duration)
|
||||
log.Debugf("Sleeping for %v...", duration)
|
||||
time.Sleep(duration)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package cmdline
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/rancher/os/pkg/util"
|
||||
|
||||
@@ -125,11 +126,34 @@ 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{}{}
|
||||
|
||||
outer:
|
||||
for _, part := range strings.Split(cmdLine, " ") {
|
||||
for _, part := range splitCmdLine(cmdLine) {
|
||||
if strings.HasPrefix(part, "cc.") {
|
||||
part = part[3:]
|
||||
} else if !strings.HasPrefix(part, "rancher.") {
|
||||
|
||||
@@ -123,6 +123,12 @@ 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",
|
||||
@@ -158,6 +164,24 @@ 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) {
|
||||
|
||||
@@ -55,6 +55,7 @@ var schema = `{
|
||||
"restart_services": {"type": "array"},
|
||||
"hypervisor_service": {"type": "boolean"},
|
||||
"shutdown_timeout": {"type": "integer"},
|
||||
"http_load_retries": {"type": "integer"},
|
||||
"preload_wait": {"type": "boolean"}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -152,6 +152,7 @@ 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"`
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
rancher:
|
||||
shutdown_timeout: 60
|
||||
http_load_retries: 6
|
||||
environment:
|
||||
VERSION: {{.VERSION}}
|
||||
SUFFIX: {{.SUFFIX}}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"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"
|
||||
@@ -57,6 +58,27 @@ 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)
|
||||
return err != nil
|
||||
}
|
||||
@@ -134,6 +156,13 @@ 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
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cloudinit
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -27,6 +28,22 @@ func CloudInit(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
||||
cfg.Rancher.CloudInit.Datasources = append(cfg.Rancher.CloudInit.Datasources, hypervisor)
|
||||
}
|
||||
|
||||
exoscale, err := onlyExoscale()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
if exoscale {
|
||||
cfg.Rancher.CloudInit.Datasources = append([]string{"exoscale"}, cfg.Rancher.CloudInit.Datasources...)
|
||||
}
|
||||
|
||||
proxmox, err := onlyProxmox()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
if proxmox {
|
||||
cfg.Rancher.CloudInit.Datasources = append([]string{"proxmox"}, cfg.Rancher.CloudInit.Datasources...)
|
||||
}
|
||||
|
||||
if len(cfg.Rancher.CloudInit.Datasources) == 0 {
|
||||
log.Info("No specific datasources, ignore cloudinit")
|
||||
return cfg, nil
|
||||
@@ -133,3 +150,21 @@ func onlyDigitalOcean(datasources []string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func onlyExoscale() (bool, error) {
|
||||
f, err := ioutil.ReadFile("/sys/class/dmi/id/product_name")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return strings.HasPrefix(string(f), "Exoscale"), nil
|
||||
}
|
||||
|
||||
func onlyProxmox() (bool, error) {
|
||||
f, err := ioutil.ReadFile("/sys/class/dmi/id/product_name")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return strings.Contains(string(f), "Proxmox"), nil
|
||||
}
|
||||
|
||||
@@ -4,22 +4,18 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/os/config"
|
||||
httpRetry "github.com/rancher/os/config/cloudinit/pkg"
|
||||
"github.com/rancher/os/pkg/log"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
composeConfig "github.com/docker/libcompose/config"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultTimeout = 10 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNoNetwork = errors.New("Networking not available to load resource")
|
||||
ErrNotFound = errors.New("Failed to find resource")
|
||||
@@ -113,29 +109,20 @@ func LoadFromNetwork(location string) ([]byte, error) {
|
||||
}
|
||||
SetProxyEnvironmentVariables()
|
||||
|
||||
var resp *http.Response
|
||||
log.Debugf("LoadFromNetwork(%s)", location)
|
||||
netClient := &http.Client{
|
||||
Timeout: defaultTimeout,
|
||||
net.DefaultResolver.PreferGo = true
|
||||
cfg := config.LoadConfig()
|
||||
client := httpRetry.NewHTTPClient()
|
||||
client.MaxRetries = cfg.Rancher.HTTPLoadRetries
|
||||
log.Debugf("start trying LoadFromNetwork(%s)", location)
|
||||
bytes, err := client.GetRetry(location)
|
||||
if err != nil {
|
||||
log.Errorf("failed to LoadFromNetwork: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
resp, err = netClient.Get(location)
|
||||
log.Debugf("LoadFromNetwork(%s) returned %v, %v", location, resp, err)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("non-200 http response: %d", resp.StatusCode)
|
||||
}
|
||||
log.Debugf("LoadFromNetwork(%s) returned", location)
|
||||
cacheAdd(location, bytes)
|
||||
|
||||
bytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cacheAdd(location, bytes)
|
||||
return bytes, nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
return bytes, nil
|
||||
}
|
||||
|
||||
func LoadResource(location string, network bool) ([]byte, error) {
|
||||
|
||||
3
scripts/tools/collect_rancheros_info.sh
Normal file → Executable file
3
scripts/tools/collect_rancheros_info.sh
Normal file → Executable file
@@ -46,6 +46,9 @@ docker info > $dest_conf_dir/docker-info
|
||||
cat /proc/mounts > $dest_conf_dir/proc-mounts
|
||||
cat /proc/1/mounts > $dest_conf_dir/proc-1-mounts
|
||||
cat /proc/cmdline > $dest_conf_dir/cmdline
|
||||
ip a > $dest_conf_dir/ipall
|
||||
ip route > $dest_conf_dir/iproutes
|
||||
cat /etc/resolv.conf > $dest_conf_dir/resolv
|
||||
dmesg > $dest_conf_dir/dmesg.log
|
||||
|
||||
cd $conf_file_src_dir && cp -rf `ls | grep -E -v "^(pem)$"` $dest_conf_dir
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
# cd scripts/tools/
|
||||
# wget https://link/rancheros-xxx.iso
|
||||
# wget http://link/custom.crt
|
||||
#
|
||||
# ./flush_crt_iso.sh --iso rancheros-vmware-autoformat.iso --cert custom.crt
|
||||
# # or
|
||||
# ./flush_crt_iso.sh --initrd initrd-xxxx --cert custom.crt
|
||||
#
|
||||
# exit
|
||||
# ls ./build/
|
||||
#
|
||||
@@ -21,6 +25,10 @@ mkdir -p ${ORIGIN_DIR} ${NEW_DIR} ${WORK_DIR} ${DAPPER_SOURCE}/build
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case $1 in
|
||||
--initrd)
|
||||
shift 1
|
||||
INITRD_FILE=$(readlink -f $1)
|
||||
;;
|
||||
--iso)
|
||||
shift 1
|
||||
ISO_FILE=$(readlink -f $1)
|
||||
@@ -36,6 +44,30 @@ while [ "$#" -gt 0 ]; do
|
||||
shift 1
|
||||
done
|
||||
|
||||
function rebuild_initrd() {
|
||||
local initrd_name=$1
|
||||
local output_dir=$2
|
||||
|
||||
# update and rebuild the initrd
|
||||
pushd ${WORK_DIR}
|
||||
mv initrd-* ${initrd_name}.gz
|
||||
gzip -d ${initrd_name}.gz
|
||||
cpio -i -F ${initrd_name}
|
||||
rm -f ${initrd_name}
|
||||
|
||||
cat ${CERT_FILE} >> ${WORK_DIR}/usr/etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
find | cpio -H newc -o | gzip -9 > ${output_dir}/${initrd_name}
|
||||
popd
|
||||
}
|
||||
|
||||
|
||||
if [ ! -z ${INITRD_FILE} ]; then
|
||||
cp ${INITRD_FILE} ${WORK_DIR}/
|
||||
rebuild_initrd $(basename ${INITRD_FILE}) ${DAPPER_SOURCE}/build/
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# copy the iso content
|
||||
mount -t iso9660 -o loop ${ISO_FILE} ${ORIGIN_DIR}
|
||||
cp -rf ${ORIGIN_DIR}/* ${NEW_DIR}
|
||||
@@ -44,17 +76,7 @@ cp -rf ${ORIGIN_DIR}/* ${NEW_DIR}
|
||||
INITRD_NAME=$(basename ${ORIGIN_DIR}/boot/initrd-*)
|
||||
cp ${ORIGIN_DIR}/boot/initrd-* ${WORK_DIR}/
|
||||
|
||||
# update and rebuild the initrd
|
||||
pushd ${WORK_DIR}
|
||||
mv initrd-* ${INITRD_NAME}.gz
|
||||
gzip -d ${INITRD_NAME}.gz
|
||||
cpio -i -F ${INITRD_NAME}
|
||||
rm -f ${INITRD_NAME}
|
||||
|
||||
cat ${CERT_FILE} >> ${WORK_DIR}/usr/etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
find | cpio -H newc -o | gzip -9 > ${NEW_DIR}/boot/${INITRD_NAME}
|
||||
popd
|
||||
rebuild_initrd ${INITRD_NAME} ${NEW_DIR}/boot
|
||||
|
||||
pushd ${NEW_DIR}
|
||||
xorriso \
|
||||
|
||||
85
scripts/tools/flush_crt_nbd.sh
Normal file
85
scripts/tools/flush_crt_nbd.sh
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
|
||||
# How to use:
|
||||
# make shell-bind
|
||||
# cd scripts/tools/
|
||||
# wget https://link/rancheros-xxx.img
|
||||
# wget http://link/custom.crt
|
||||
#
|
||||
# ./flush_crt_nbd.sh --img rancheros-openstack.img --cert custom.crt
|
||||
# # or
|
||||
# ./flush_crt_nbd.sh --initrd initrd-xxxx --cert custom.crt
|
||||
#
|
||||
# exit
|
||||
# ls ./build/
|
||||
#
|
||||
|
||||
set -ex
|
||||
|
||||
BASE_DIR=/tmp
|
||||
ORIGIN_DIR=/tmp/origin
|
||||
WORK_DIR=/tmp/work
|
||||
|
||||
mkdir -p ${ORIGIN_DIR} ${WORK_DIR} ${DAPPER_SOURCE}/build
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case $1 in
|
||||
--initrd)
|
||||
shift 1
|
||||
INITRD_FILE=$(readlink -f $1)
|
||||
;;
|
||||
--img)
|
||||
shift 1
|
||||
IMG_FILE=$(readlink -f $1)
|
||||
;;
|
||||
--cert)
|
||||
shift 1
|
||||
CERT_FILE=$(readlink -f $1)
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift 1
|
||||
done
|
||||
|
||||
function rebuild_initrd() {
|
||||
local initrd_name=$1
|
||||
local output_dir=$2
|
||||
|
||||
# update and rebuild the initrd
|
||||
pushd ${WORK_DIR}
|
||||
mv initrd-* ${initrd_name}.gz
|
||||
gzip -d ${initrd_name}.gz
|
||||
cpio -i -F ${initrd_name}
|
||||
rm -f ${initrd_name}
|
||||
cat ${CERT_FILE} >> ${WORK_DIR}/usr/etc/ssl/certs/ca-certificates.crt
|
||||
find | cpio -H newc -o | gzip -9 > ${output_dir}/${initrd_name}
|
||||
popd
|
||||
}
|
||||
|
||||
|
||||
if [ ! -z ${INITRD_FILE} ]; then
|
||||
cp ${INITRD_FILE} ${WORK_DIR}/
|
||||
rebuild_initrd $(basename ${INITRD_FILE}) ${DAPPER_SOURCE}/build/
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# copy the iso content
|
||||
cp -a ${IMG_FILE} ${IMG_FILE}_new
|
||||
qemu-nbd -c /dev/nbd0 --partition=1 ${IMG_FILE}_new
|
||||
mount /dev/nbd0 ${ORIGIN_DIR}
|
||||
|
||||
# copy the initrd file
|
||||
INITRD_NAME=$(basename ${ORIGIN_DIR}/boot/initrd-*)
|
||||
cp ${ORIGIN_DIR}/boot/initrd-* ${WORK_DIR}/
|
||||
|
||||
rebuild_initrd ${INITRD_NAME} ${ORIGIN_DIR}/boot
|
||||
|
||||
# copy out
|
||||
umount ${ORIGIN_DIR}
|
||||
qemu-nbd -d /dev/nbd0
|
||||
mv ${IMG_FILE}_new ${DAPPER_SOURCE}/build/$(basename ${IMG_FILE})
|
||||
|
||||
# cleanup
|
||||
rm -rf ${WORK_DIR}/
|
||||
@@ -29,7 +29,7 @@ github.com/sigma/vmw-ovflib master
|
||||
github.com/sigma/bdoor master
|
||||
github.com/stretchr/testify a1f97990ddc16022ec7610326dd9bce31332c116
|
||||
github.com/vbatts/tar-split v0.9.11
|
||||
github.com/vishvananda/netlink f5a6f697a596c788d474984a38a0ac4ba0719e93
|
||||
github.com/vishvananda/netlink b76f71f1d33745ac0833fff4277481599a8ee73f https://github.com/niusmallnan/netlink
|
||||
github.com/vishvananda/netns 54f0e4339ce73702a0607f49922aaa1e749b418d
|
||||
github.com/xeipuuv/gojsonpointer 6fe8760cad3569743d51ddbb243b26f8456742dc
|
||||
github.com/xeipuuv/gojsonreference e02fc20de94c78484cd5ffb007f8af96be030a45
|
||||
|
||||
7
vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
7
vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
@@ -103,14 +103,17 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||
}
|
||||
}
|
||||
|
||||
if addr.Broadcast == nil {
|
||||
if addr.Broadcast == nil && prefixlen < 31 {
|
||||
calcBroadcast := make(net.IP, masklen/8)
|
||||
for i := range localAddrData {
|
||||
calcBroadcast[i] = localAddrData[i] | ^addr.Mask[i]
|
||||
}
|
||||
addr.Broadcast = calcBroadcast
|
||||
}
|
||||
req.AddData(nl.NewRtAttr(syscall.IFA_BROADCAST, addr.Broadcast))
|
||||
|
||||
if addr.Broadcast != nil {
|
||||
req.AddData(nl.NewRtAttr(syscall.IFA_BROADCAST, addr.Broadcast))
|
||||
}
|
||||
|
||||
if addr.Label != "" {
|
||||
labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label))
|
||||
|
||||
Reference in New Issue
Block a user