Unverified Commit 5753dbd6 authored by Erik Wilson's avatar Erik Wilson Committed by GitHub

Merge branch 'master' into selinux-install

parents 429e9d49 65f7fbe5
./bin ./bin
./etc ./etc
./build/data
./build/data.tar.gz
./pkg/data/zz_generated_bindata.go ./pkg/data/zz_generated_bindata.go
./package/data.tar.gz
./.vagrant ./.vagrant
./.cache ./.cache
./.dapper ./.dapper
./data-dir
./dist
./.trash-cache ./.trash-cache
...@@ -59,6 +59,31 @@ steps: ...@@ -59,6 +59,31 @@ steps:
event: event:
- tag - tag
- name: rpm-publish
image: centos:7
environment:
PRIVATE_KEY:
from_secret: private_key
PRIVATE_KEY_PASS_PHRASE:
from_secret: private_key_pass_phrase
AWS_S3_BUCKET:
from_secret: aws_s3_bucket
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
commands:
- scripts/provision/generic/centos7/yum-install-rpm-tools
- scripts/package-rpm
when:
instance:
- drone-publish.rancher.io
ref:
- refs/head/master
- refs/tags/*
event:
- tag
- name: test - name: test
image: rancher/dapper:v0.4.2 image: rancher/dapper:v0.4.2
secrets: [ gcloud_auth ] secrets: [ gcloud_auth ]
...@@ -154,6 +179,31 @@ steps: ...@@ -154,6 +179,31 @@ steps:
event: event:
- tag - tag
- name: rpm-publish
image: centos:7
environment:
PRIVATE_KEY:
from_secret: private_key
PRIVATE_KEY_PASS_PHRASE:
from_secret: private_key_pass_phrase
AWS_S3_BUCKET:
from_secret: aws_s3_bucket
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
commands:
- scripts/provision/generic/centos7/yum-install-rpm-tools
- scripts/package-rpm
when:
instance:
- drone-publish.rancher.io
ref:
- refs/head/master
- refs/tags/*
event:
- tag
- name: test - name: test
image: rancher/dapper:v0.4.2 image: rancher/dapper:v0.4.2
secrets: [ gcloud_auth ] secrets: [ gcloud_auth ]
...@@ -273,16 +323,56 @@ steps: ...@@ -273,16 +323,56 @@ steps:
- DOCKER_USERNAME - DOCKER_USERNAME
- DOCKER_PASSWORD - DOCKER_PASSWORD
- DRONE_TAG - DRONE_TAG
when:
instance: trigger:
instance:
- drone-publish.rancher.io
ref:
- refs/head/master
- refs/tags/*
event:
- tag
depends_on:
- amd64
- arm64
- arm
---
kind: pipeline
name: dispatch
platform:
os: linux
arch: amd64
steps:
- name: dispatch
image: rancher/dapper:v0.4.2
environment:
PAT_USERNAME:
from_secret: pat_username
PAT_TOKEN:
from_secret: github_token
commands:
- dapper dispatch
volumes:
- name: docker
path: /var/run/docker.sock
trigger:
instance:
- drone-publish.rancher.io - drone-publish.rancher.io
ref: ref:
- refs/head/master - refs/head/master
- refs/tags/* - refs/tags/*
event: event:
- tag - tag
volumes:
- name: docker
host:
path: /var/run/docker.sock
depends_on: depends_on:
- amd64 - manifest
- arm64 \ No newline at end of file
- arm
...@@ -28,3 +28,4 @@ __pycache__ ...@@ -28,3 +28,4 @@ __pycache__
/tests/.tox/ /tests/.tox/
/tests/.vscode /tests/.vscode
/sonobuoy-output /sonobuoy-output
*.tmp
FROM golang:1.13.8-alpine3.10 FROM golang:1.13.8-alpine3.10
RUN apk -U --no-cache add bash git gcc musl-dev docker vim less file curl wget ca-certificates jq linux-headers zlib-dev tar zip squashfs-tools npm coreutils \ RUN apk -U --no-cache add bash git gcc musl-dev docker vim less file curl wget ca-certificates jq linux-headers zlib-dev tar zip squashfs-tools npm coreutils \
python2 python3 py3-pip python3-dev openssl-dev libffi-dev libseccomp libseccomp-dev make libuv-static python2 openssl-dev libffi-dev libseccomp libseccomp-dev make libuv-static
RUN pip3 install 'tox==3.6.0'
RUN apk -U --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/main/ add sqlite-dev sqlite-static RUN apk -U --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/main/ add sqlite-dev sqlite-static libselinux libselinux-dev
RUN mkdir -p /go/src/golang.org/x && \ RUN mkdir -p /go/src/golang.org/x && \
cd /go/src/golang.org/x && git clone https://github.com/golang/tools && \ cd /go/src/golang.org/x && git clone https://github.com/golang/tools && cd tools && \
git -C /go/src/golang.org/x/tools checkout -b current aa82965741a9fecd12b026fbb3d3c6ed3231b8f8 && \ git checkout -b current aa82965741a9fecd12b026fbb3d3c6ed3231b8f8 && \
go install golang.org/x/tools/cmd/goimports go install golang.org/x/tools/cmd/goimports && cd
RUN rm -rf /go/src /go/pkg RUN rm -rf /go/src /go/pkg
ARG DAPPER_HOST_ARCH ARG DAPPER_HOST_ARCH
...@@ -17,6 +17,9 @@ RUN if [ "${ARCH}" == "amd64" ]; then \ ...@@ -17,6 +17,9 @@ RUN if [ "${ARCH}" == "amd64" ]; then \
curl -sL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s v1.15.0; \ curl -sL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s v1.15.0; \
fi fi
ARG SELINUX=true
ENV SELINUX $SELINUX
ARG DQLITE=true ARG DQLITE=true
ENV DQLITE $DQLITE ENV DQLITE $DQLITE
COPY --from=rancher/dqlite-build:v1.3.1-r1 /dist/artifacts /usr/src/ COPY --from=rancher/dqlite-build:v1.3.1-r1 /dist/artifacts /usr/src/
......
BOX = "generic/alpine310" OS = (ENV['OS'] || "alpine310")
BOX_REPO = (ENV['BOX_REPO'] || "generic")
HOME = File.dirname(__FILE__) HOME = File.dirname(__FILE__)
PROJECT = File.basename(HOME) PROJECT = File.basename(HOME)
MOUNT_TYPE = ENV['MOUNT_TYPE'] || "nfs"
NUM_NODES = (ENV['NUM_NODES'] || 0).to_i NUM_NODES = (ENV['NUM_NODES'] || 0).to_i
NODE_CPUS = (ENV['NODE_CPUS'] || 4).to_i NODE_CPUS = (ENV['NODE_CPUS'] || 4).to_i
NODE_MEMORY = (ENV['NODE_MEMORY'] || 8192).to_i NODE_MEMORY = (ENV['NODE_MEMORY'] || 8192).to_i
NETWORK_PREFIX = ENV['NETWORK_PREFIX'] || "10.135.135" NETWORK_PREFIX = ENV['NETWORK_PREFIX'] || "10.135.135"
VAGRANT_PROVISION = ENV['VAGRANT_PROVISION'] || "./scripts/vagrant-provision" VAGRANT_PROVISION = ENV['VAGRANT_PROVISION'] || "./scripts/provision/vagrant"
MOUNT_TYPE = ENV['MOUNT_TYPE'] || "nfs"
# --- Rules for /etc/sudoers to avoid password entry configuring NFS: # --- Rules for /etc/sudoers to avoid password entry configuring NFS:
# %admin ALL = (root) NOPASSWD: /usr/bin/sed -E -e * -ibak /etc/exports # %admin ALL = (root) NOPASSWD: /usr/bin/sed -E -e * -ibak /etc/exports
...@@ -14,61 +15,36 @@ VAGRANT_PROVISION = ENV['VAGRANT_PROVISION'] || "./scripts/vagrant-provision" ...@@ -14,61 +15,36 @@ VAGRANT_PROVISION = ENV['VAGRANT_PROVISION'] || "./scripts/vagrant-provision"
# %admin ALL = (root) NOPASSWD: /sbin/nfsd restart # %admin ALL = (root) NOPASSWD: /sbin/nfsd restart
# --- May need to add terminal to System Preferences -> Security & Privacy -> Privacy -> Full Disk Access # --- May need to add terminal to System Preferences -> Security & Privacy -> Privacy -> Full Disk Access
# --- Check for missing plugins def provision(vm, node_num)
required_plugins = %w( vagrant-alpine vagrant-timezone ) node_os = (ENV["OS_#{node_num}"] || OS)
plugin_installed = false vm.box = (ENV["BOX_#{node_num}"] || ENV["BOX"] || "#{BOX_REPO}/#{node_os}")
required_plugins.each do |plugin| vm.hostname = "#{PROJECT}-#{node_num}-#{node_os}"
unless Vagrant.has_plugin?(plugin) vm.network "private_network", ip: "#{NETWORK_PREFIX}.#{100+node_num}"
system "vagrant plugin install #{plugin}" vm.provision "shell",
plugin_installed = true path: VAGRANT_PROVISION,
end env: { 'HOME' => HOME, 'GOPATH' => ENV['GOPATH'], 'BOX' => vm.box }
end end
# --- If new plugins installed, restart Vagrant process
if plugin_installed === true
exec "vagrant #{ARGV.join' '}"
end
provision = <<SCRIPT
# --- Use system gopath if available
export GOPATH=#{ENV['GOPATH']}
# --- Default to root user for vagrant ssh
cat <<\\EOF >/etc/profile.d/root.sh
[ $EUID -ne 0 ] && exec sudo -i
EOF
# --- Set home to current directory
cat <<\\EOF >/etc/profile.d/home.sh
export HOME="#{HOME}" && cd
EOF
. /etc/profile.d/home.sh
# --- Run vagrant provision script if available
if [ ! -x #{VAGRANT_PROVISION} ]; then
echo 'WARNING: Unable to execute provision script "#{VAGRANT_PROVISION}"'
exit
fi
echo "running '#{VAGRANT_PROVISION}'..." && \
#{VAGRANT_PROVISION} && \
echo "finished '#{VAGRANT_PROVISION}'!"
SCRIPT
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
config.vm.provider "virtualbox" do |v| config.vm.provider "virtualbox" do |v|
v.cpus = NODE_CPUS v.cpus = NODE_CPUS
v.memory = NODE_MEMORY v.memory = NODE_MEMORY
v.customize ["modifyvm", :id, "--audio", "none"] v.customize ["modifyvm", :id, "--audio", "none"]
end end
if Vagrant.has_plugin?("vagrant-timezone")
config.vm.box = BOX config.timezone.value = :host
config.vm.hostname = PROJECT end
config.vm.synced_folder ".", HOME, type: MOUNT_TYPE config.vm.synced_folder ".", HOME, type: MOUNT_TYPE
config.vm.provision "shell", inline: provision
config.timezone.value = :host
config.vm.network "private_network", ip: "#{NETWORK_PREFIX}.100" if NUM_NODES==0 if NUM_NODES==0
provision(config.vm, 0)
(1..NUM_NODES).each do |i| else
config.vm.define ".#{i}" do |node| (1..NUM_NODES).each do |i|
node.vm.network "private_network", ip: "#{NETWORK_PREFIX}.#{100+i}" config.vm.define ".#{i}" do |node|
node.vm.hostname = "#{PROJECT}-#{i}" provision(node.vm, i)
end
end end
end end
end end
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
Description=Lightweight Kubernetes Description=Lightweight Kubernetes
Documentation=https://k3s.io Documentation=https://k3s.io
After=network-online.target After=network-online.target
[Service] [Service]
Type=notify
ExecStartPre=-/sbin/modprobe br_netfilter ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s server {{ extra_server_args | default("") }} ExecStart=/usr/local/bin/k3s server {{ extra_server_args | default("") }}
...@@ -12,6 +14,7 @@ LimitNOFILE=infinity ...@@ -12,6 +14,7 @@ LimitNOFILE=infinity
LimitNPROC=infinity LimitNPROC=infinity
LimitCORE=infinity LimitCORE=infinity
TasksMax=infinity TasksMax=infinity
TimeoutStartSec=infinity
Restart=always Restart=always
RestartSec=5s RestartSec=5s
......
...@@ -2,7 +2,11 @@ ...@@ -2,7 +2,11 @@
Description=Lightweight Kubernetes Description=Lightweight Kubernetes
Documentation=https://k3s.io Documentation=https://k3s.io
After=network-online.target After=network-online.target
[Service] [Service]
Type=notify
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s agent --server https://{{ master_ip }}:6443 --token {{ hostvars[groups['master'][0]]['token'] }} ExecStart=/usr/local/bin/k3s agent --server https://{{ master_ip }}:6443 --token {{ hostvars[groups['master'][0]]['token'] }}
KillMode=process KillMode=process
Delegate=yes Delegate=yes
...@@ -10,6 +14,7 @@ LimitNOFILE=infinity ...@@ -10,6 +14,7 @@ LimitNOFILE=infinity
LimitNPROC=infinity LimitNPROC=infinity
LimitCORE=infinity LimitCORE=infinity
TasksMax=infinity TasksMax=infinity
TimeoutStartSec=infinity
Restart=always Restart=always
RestartSec=5s RestartSec=5s
......
...@@ -7,9 +7,9 @@ replace ( ...@@ -7,9 +7,9 @@ replace (
github.com/containerd/btrfs => github.com/containerd/btrfs v0.0.0-20181101203652-af5082808c83 github.com/containerd/btrfs => github.com/containerd/btrfs v0.0.0-20181101203652-af5082808c83
github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601 github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601
github.com/containerd/console => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 github.com/containerd/console => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50
github.com/containerd/containerd => github.com/rancher/containerd v1.3.3-k3s1 github.com/containerd/containerd => github.com/rancher/containerd v1.3.3-k3s2
github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02
github.com/containerd/cri => github.com/rancher/cri v1.3.0-k3s.3 github.com/containerd/cri => github.com/rancher/cri v1.3.0-k3s.4
github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c
github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda
github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd
...@@ -94,6 +94,7 @@ require ( ...@@ -94,6 +94,7 @@ require (
github.com/mattn/go-sqlite3 v1.13.0 github.com/mattn/go-sqlite3 v1.13.0
github.com/natefinch/lumberjack v2.0.0+incompatible github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/opencontainers/runc v1.0.0-rc9 github.com/opencontainers/runc v1.0.0-rc9
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8 // indirect github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8 // indirect
github.com/rancher/dynamiclistener v0.2.0 github.com/rancher/dynamiclistener v0.2.0
...@@ -122,6 +123,5 @@ require ( ...@@ -122,6 +123,5 @@ require (
k8s.io/component-base v0.0.0 k8s.io/component-base v0.0.0
k8s.io/cri-api v0.0.0 k8s.io/cri-api v0.0.0
k8s.io/klog v1.0.0 k8s.io/klog v1.0.0
k8s.io/kubelet v0.0.0
k8s.io/kubernetes v1.16.0 k8s.io/kubernetes v1.16.0
) )
...@@ -708,10 +708,10 @@ github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1: ...@@ -708,10 +708,10 @@ github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:
github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI= github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI=
github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8 h1:83l9gPhYtgxODlZKU0Odq4pQuDcMZEVgAh364+PV3OU= github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8 h1:83l9gPhYtgxODlZKU0Odq4pQuDcMZEVgAh364+PV3OU=
github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8/go.mod h1:4XHkfaUj+URzGO9sohoAgt2V9Y8nIW7fugpu0E6gShk= github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8/go.mod h1:4XHkfaUj+URzGO9sohoAgt2V9Y8nIW7fugpu0E6gShk=
github.com/rancher/containerd v1.3.3-k3s1 h1:j8NGZdXKsZd2ne0XQg6OBfMJ/NkY/Qri6QhscGrJp2M= github.com/rancher/containerd v1.3.3-k3s2 h1:RZr+TqFt7+YsrSYkyytlhW4HmneWeFNM7IymNOoGW6A=
github.com/rancher/containerd v1.3.3-k3s1/go.mod h1:ZMfzmqce2Z+QSEqdHMfeJs1TZ/UeJ1aDrazjpQT4ehM= github.com/rancher/containerd v1.3.3-k3s2/go.mod h1:ZMfzmqce2Z+QSEqdHMfeJs1TZ/UeJ1aDrazjpQT4ehM=
github.com/rancher/cri v1.3.0-k3s.3 h1:j/Sq2LMyg6gBn2MS1j5dEudpdL+UYVH7ubbewUCXkS0= github.com/rancher/cri v1.3.0-k3s.4 h1:BXER8109dxgNw4qq8HHOCJ+3sHO+9AA1cwZTOLlqoTo=
github.com/rancher/cri v1.3.0-k3s.3/go.mod h1:Ht5T1dIKzm+4NExmb7wDVG6qR+j0xeXIjjhCv1d9geY= github.com/rancher/cri v1.3.0-k3s.4/go.mod h1:Ht5T1dIKzm+4NExmb7wDVG6qR+j0xeXIjjhCv1d9geY=
github.com/rancher/cri-tools v1.17.0-k3s1 h1:jfu97FowbraTDc7b6fxWtO+dq+DU2oW+ABBQSEFiRb0= github.com/rancher/cri-tools v1.17.0-k3s1 h1:jfu97FowbraTDc7b6fxWtO+dq+DU2oW+ABBQSEFiRb0=
github.com/rancher/cri-tools v1.17.0-k3s1/go.mod h1:bRTZttsvk+nCG8tSFs8D6UUx8CkMXR5TAsRLS0fXAqI= github.com/rancher/cri-tools v1.17.0-k3s1/go.mod h1:bRTZttsvk+nCG8tSFs8D6UUx8CkMXR5TAsRLS0fXAqI=
github.com/rancher/dynamiclistener v0.2.0 h1:KucYwJXVVGhZ/NndfMCeQoCafT/VN7kvqSGgmlX8Lxk= github.com/rancher/dynamiclistener v0.2.0 h1:KucYwJXVVGhZ/NndfMCeQoCafT/VN7kvqSGgmlX8Lxk=
......
...@@ -26,6 +26,9 @@ set -e ...@@ -26,6 +26,9 @@ set -e
# If set to 'skip' will not create symlinks, 'force' will overwrite, # If set to 'skip' will not create symlinks, 'force' will overwrite,
# default will symlink if command does not exist in path. # default will symlink if command does not exist in path.
# #
# - INSTALL_K3S_SKIP_ENABLE
# If set to true will not enable or start k3s service.
#
# - INSTALL_K3S_SKIP_START # - INSTALL_K3S_SKIP_START
# If set to true will not start k3s service. # If set to true will not start k3s service.
# #
...@@ -166,11 +169,6 @@ setup_env() { ...@@ -166,11 +169,6 @@ setup_env() {
${invalid_chars}" ${invalid_chars}"
fi fi
# --- set related files from system name ---
SERVICE_K3S=${SYSTEM_NAME}.service
UNINSTALL_K3S_SH=${SYSTEM_NAME}-uninstall.sh
KILLALL_K3S_SH=k3s-killall.sh
# --- use sudo if we are not already root --- # --- use sudo if we are not already root ---
SUDO=sudo SUDO=sudo
if [ $(id -u) -eq 0 ]; then if [ $(id -u) -eq 0 ]; then
...@@ -202,6 +200,11 @@ setup_env() { ...@@ -202,6 +200,11 @@ setup_env() {
SYSTEMD_DIR=/etc/systemd/system SYSTEMD_DIR=/etc/systemd/system
fi fi
# --- set related files from system name ---
SERVICE_K3S=${SYSTEM_NAME}.service
UNINSTALL_K3S_SH=${UNINSTALL_K3S_SH:-${BIN_DIR}/${SYSTEM_NAME}-uninstall.sh}
KILLALL_K3S_SH=${KILLALL_K3S_SH:-${BIN_DIR}/k3s-killall.sh}
# --- use service or environment location depending on systemd/openrc --- # --- use service or environment location depending on systemd/openrc ---
if [ "${HAS_SYSTEMD}" = true ]; then if [ "${HAS_SYSTEMD}" = true ]; then
FILE_K3S_SERVICE=${SYSTEMD_DIR}/${SERVICE_K3S} FILE_K3S_SERVICE=${SYSTEMD_DIR}/${SERVICE_K3S}
...@@ -389,7 +392,7 @@ setup_binary() { ...@@ -389,7 +392,7 @@ setup_binary() {
if ! $SUDO chcon -u system_u -r object_r -t container_runtime_exec_t ${BIN_DIR}/k3s 2>/dev/null 2>&1; then if ! $SUDO chcon -u system_u -r object_r -t container_runtime_exec_t ${BIN_DIR}/k3s 2>/dev/null 2>&1; then
if $SUDO grep SELINUX=enforcing /etc/selinux/config >/dev/null 2>&1; then if $SUDO grep SELINUX=enforcing /etc/selinux/config >/dev/null 2>&1; then
fatal "Failed to apply container_runtime_exec_t to ${BIN_DIR}/k3s, please install k3s_selinux RPM" fatal "Failed to apply container_runtime_exec_t to ${BIN_DIR}/k3s, please install k3s-selinux RPM"
fi fi
fi fi
} }
...@@ -425,7 +428,7 @@ create_symlinks() { ...@@ -425,7 +428,7 @@ create_symlinks() {
for cmd in kubectl crictl ctr; do for cmd in kubectl crictl ctr; do
if [ ! -e ${BIN_DIR}/${cmd} ] || [ "${INSTALL_K3S_SYMLINK}" = force ]; then if [ ! -e ${BIN_DIR}/${cmd} ] || [ "${INSTALL_K3S_SYMLINK}" = force ]; then
which_cmd=$(which ${cmd} || true) which_cmd=$(which ${cmd} 2>/dev/null || true)
if [ -z "${which_cmd}" ] || [ "${INSTALL_K3S_SYMLINK}" = force ]; then if [ -z "${which_cmd}" ] || [ "${INSTALL_K3S_SYMLINK}" = force ]; then
info "Creating ${BIN_DIR}/${cmd} symlink to k3s" info "Creating ${BIN_DIR}/${cmd} symlink to k3s"
$SUDO ln -sf k3s ${BIN_DIR}/${cmd} $SUDO ln -sf k3s ${BIN_DIR}/${cmd}
...@@ -441,13 +444,13 @@ create_symlinks() { ...@@ -441,13 +444,13 @@ create_symlinks() {
# --- create killall script --- # --- create killall script ---
create_killall() { create_killall() {
[ "${INSTALL_K3S_BIN_DIR_READ_ONLY}" = true ] && return [ "${INSTALL_K3S_BIN_DIR_READ_ONLY}" = true ] && return
info "Creating killall script ${BIN_DIR}/${KILLALL_K3S_SH}" info "Creating killall script ${KILLALL_K3S_SH}"
$SUDO tee ${BIN_DIR}/${KILLALL_K3S_SH} >/dev/null << \EOF $SUDO tee ${KILLALL_K3S_SH} >/dev/null << \EOF
#!/bin/sh #!/bin/sh
[ $(id -u) -eq 0 ] || exec sudo $0 $@ [ $(id -u) -eq 0 ] || exec sudo $0 $@
for bin in /var/lib/rancher/k3s/data/**/bin/; do for bin in /var/lib/rancher/k3s/data/**/bin/; do
[ -d $bin ] && export PATH=$bin:$PATH [ -d $bin ] && export PATH=$PATH:$bin:$bin/aux
done done
set -x set -x
...@@ -485,7 +488,7 @@ killtree() { ...@@ -485,7 +488,7 @@ killtree() {
} }
getshims() { getshims() {
lsof | sed -e 's/^[^0-9]*//g; s/ */\t/g' | grep -w 'k3s/data/[^/]*/bin/containerd-shim' | cut -f1 | sort -n -u ps -e -o pid= -o args= | sed -e 's/^ *//; s/\s\s*/\t/;' | grep -w 'k3s/data/[^/]*/bin/containerd-shim' | cut -f1
} }
killtree $({ set +x; } 2>/dev/null; getshims; set -x) killtree $({ set +x; } 2>/dev/null; getshims; set -x)
...@@ -520,20 +523,20 @@ ip link delete flannel.1 ...@@ -520,20 +523,20 @@ ip link delete flannel.1
rm -rf /var/lib/cni/ rm -rf /var/lib/cni/
iptables-save | grep -v KUBE- | grep -v CNI- | iptables-restore iptables-save | grep -v KUBE- | grep -v CNI- | iptables-restore
EOF EOF
$SUDO chmod 755 ${BIN_DIR}/${KILLALL_K3S_SH} $SUDO chmod 755 ${KILLALL_K3S_SH}
$SUDO chown root:root ${BIN_DIR}/${KILLALL_K3S_SH} $SUDO chown root:root ${KILLALL_K3S_SH}
} }
# --- create uninstall script --- # --- create uninstall script ---
create_uninstall() { create_uninstall() {
[ "${INSTALL_K3S_BIN_DIR_READ_ONLY}" = true ] && return [ "${INSTALL_K3S_BIN_DIR_READ_ONLY}" = true ] && return
info "Creating uninstall script ${BIN_DIR}/${UNINSTALL_K3S_SH}" info "Creating uninstall script ${UNINSTALL_K3S_SH}"
$SUDO tee ${BIN_DIR}/${UNINSTALL_K3S_SH} >/dev/null << EOF $SUDO tee ${UNINSTALL_K3S_SH} >/dev/null << EOF
#!/bin/sh #!/bin/sh
set -x set -x
[ \$(id -u) -eq 0 ] || exec sudo \$0 \$@ [ \$(id -u) -eq 0 ] || exec sudo \$0 \$@
${BIN_DIR}/${KILLALL_K3S_SH} ${KILLALL_K3S_SH}
if which systemctl; then if which systemctl; then
systemctl disable ${SYSTEM_NAME} systemctl disable ${SYSTEM_NAME}
...@@ -548,7 +551,7 @@ rm -f ${FILE_K3S_SERVICE} ...@@ -548,7 +551,7 @@ rm -f ${FILE_K3S_SERVICE}
rm -f ${FILE_K3S_ENV} rm -f ${FILE_K3S_ENV}
remove_uninstall() { remove_uninstall() {
rm -f ${BIN_DIR}/${UNINSTALL_K3S_SH} rm -f ${UNINSTALL_K3S_SH}
} }
trap remove_uninstall EXIT trap remove_uninstall EXIT
...@@ -567,10 +570,10 @@ rm -rf /etc/rancher/k3s ...@@ -567,10 +570,10 @@ rm -rf /etc/rancher/k3s
rm -rf /var/lib/rancher/k3s rm -rf /var/lib/rancher/k3s
rm -rf /var/lib/kubelet rm -rf /var/lib/kubelet
rm -f ${BIN_DIR}/k3s rm -f ${BIN_DIR}/k3s
rm -f ${BIN_DIR}/${KILLALL_K3S_SH} rm -f ${KILLALL_K3S_SH}
EOF EOF
$SUDO chmod 755 ${BIN_DIR}/${UNINSTALL_K3S_SH} $SUDO chmod 755 ${UNINSTALL_K3S_SH}
$SUDO chown root:root ${BIN_DIR}/${UNINSTALL_K3S_SH} $SUDO chown root:root ${UNINSTALL_K3S_SH}
} }
# --- disable current service if loaded -- # --- disable current service if loaded --
...@@ -704,6 +707,8 @@ openrc_start() { ...@@ -704,6 +707,8 @@ openrc_start() {
# --- startup systemd or openrc service --- # --- startup systemd or openrc service ---
service_enable_and_start() { service_enable_and_start() {
[ "${INSTALL_K3S_SKIP_ENABLE}" = true ] && return
[ "${HAS_SYSTEMD}" = true ] && systemd_enable [ "${HAS_SYSTEMD}" = true ] && systemd_enable
[ "${HAS_OPENRC}" = true ] && openrc_enable [ "${HAS_OPENRC}" = true ] && openrc_enable
......
# vim: sw=4:ts=4:et
%define install_path /usr/bin
%define util_path %{_datadir}/k3s
%define install_sh %{util_path}/.install.sh
%define uninstall_sh %{util_path}/.uninstall.sh
Name: k3s
Version: %{k3s_version}
Release: %{k3s_release}%{?dist}
Summary: Lightweight Kubernetes
Group: System Environment/Base
License: ASL 2.0
URL: http://k3s.io
BuildRequires: systemd
Requires(post): k3s-selinux >= %{k3s_policyver}
%description
The certified Kubernetes distribution built for IoT & Edge computing.
%install
install -d %{buildroot}%{install_path}
install dist/artifacts/%{k3s_binary} %{buildroot}%{install_path}/k3s
install -d %{buildroot}%{util_path}
install install.sh %{buildroot}%{install_sh}
%post
# do not run install script on upgrade
echo post-install args: $@
if [ $1 == 1 ]; then
INSTALL_K3S_BIN_DIR=%{install_path} \
INSTALL_K3S_SKIP_DOWNLOAD=true \
INSTALL_K3S_SKIP_ENABLE=true \
UNINSTALL_K3S_SH=%{uninstall_sh} \
%{install_sh}
fi
%systemd_post k3s.service
exit 0
%postun
echo post-uninstall args: $@
# do not run uninstall script on upgrade
if [ $1 == 0 ]; then
%{uninstall_sh}
rm -rf %{util_path}
fi
exit 0
%files
%{install_path}/k3s
%{install_sh}
%changelog
* Mon Mar 2 2020 Erik Wilson <erik@rancher.com> 0.1-1
- Initial version
...@@ -397,6 +397,7 @@ func get(envInfo *cmds.Agent) (*config.Node, error) { ...@@ -397,6 +397,7 @@ func get(envInfo *cmds.Agent) (*config.Node, error) {
nodeConfig := &config.Node{ nodeConfig := &config.Node{
Docker: envInfo.Docker, Docker: envInfo.Docker,
DisableSELinux: envInfo.DisableSELinux,
ContainerRuntimeEndpoint: envInfo.ContainerRuntimeEndpoint, ContainerRuntimeEndpoint: envInfo.ContainerRuntimeEndpoint,
FlannelBackend: controlConfig.FlannelBackend, FlannelBackend: controlConfig.FlannelBackend,
} }
...@@ -474,6 +475,7 @@ func get(envInfo *cmds.Agent) (*config.Node, error) { ...@@ -474,6 +475,7 @@ func get(envInfo *cmds.Agent) (*config.Node, error) {
nodeConfig.AgentConfig.DisableCCM = controlConfig.DisableCCM nodeConfig.AgentConfig.DisableCCM = controlConfig.DisableCCM
nodeConfig.AgentConfig.DisableNPC = controlConfig.DisableNPC nodeConfig.AgentConfig.DisableNPC = controlConfig.DisableNPC
nodeConfig.AgentConfig.Rootless = envInfo.Rootless nodeConfig.AgentConfig.Rootless = envInfo.Rootless
nodeConfig.DisableSELinux = envInfo.DisableSELinux
return nodeConfig, nil return nodeConfig, nil
} }
......
// +build !windows
package containerd
import (
"os/exec"
"syscall"
)
func addDeathSig(cmd *exec.Cmd) {
// not supported in this OS
cmd.SysProcAttr = &syscall.SysProcAttr{
Pdeathsig: syscall.SIGKILL,
}
}
package containerd
import "os/exec"
func addDeathSig(_ *exec.Cmd) {
// not supported in this OS
}
...@@ -8,13 +8,13 @@ import ( ...@@ -8,13 +8,13 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"syscall"
"time" "time"
"github.com/containerd/containerd" "github.com/containerd/containerd"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/natefinch/lumberjack" "github.com/natefinch/lumberjack"
"github.com/opencontainers/runc/libcontainer/system" "github.com/opencontainers/runc/libcontainer/system"
"github.com/pkg/errors"
"github.com/rancher/k3s/pkg/agent/templates" "github.com/rancher/k3s/pkg/agent/templates"
util2 "github.com/rancher/k3s/pkg/agent/util" util2 "github.com/rancher/k3s/pkg/agent/util"
"github.com/rancher/k3s/pkg/daemons/config" "github.com/rancher/k3s/pkg/daemons/config"
...@@ -66,9 +66,7 @@ func Run(ctx context.Context, cfg *config.Node) error { ...@@ -66,9 +66,7 @@ func Run(ctx context.Context, cfg *config.Node) error {
cmd := exec.Command(args[0], args[1:]...) cmd := exec.Command(args[0], args[1:]...)
cmd.Stdout = stdOut cmd.Stdout = stdOut
cmd.Stderr = stdErr cmd.Stderr = stdErr
cmd.SysProcAttr = &syscall.SysProcAttr{ addDeathSig(cmd)
Pdeathsig: syscall.SIGKILL,
}
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "containerd: %s\n", err) fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
} }
...@@ -170,6 +168,22 @@ func setupContainerdConfig(ctx context.Context, cfg *config.Node) error { ...@@ -170,6 +168,22 @@ func setupContainerdConfig(ctx context.Context, cfg *config.Node) error {
PrivateRegistryConfig: privRegistries, PrivateRegistryConfig: privRegistries,
} }
selEnabled, selConfigured, err := selinuxStatus()
if err != nil {
return errors.Wrap(err, "failed to detect selinux")
}
if cfg.DisableSELinux {
containerdConfig.SELinuxEnabled = false
if selEnabled {
logrus.Warn("SELinux is enabled for system but has been disabled for containerd by override")
}
} else {
containerdConfig.SELinuxEnabled = selEnabled
}
if containerdConfig.SELinuxEnabled && !selConfigured {
logrus.Warnf("SELinux is enabled for k3s but process is not running in context '%s', k3s-selinux policy may need to be applied", SELinuxContextType)
}
containerdTemplateBytes, err := ioutil.ReadFile(cfg.Containerd.Template) containerdTemplateBytes, err := ioutil.ReadFile(cfg.Containerd.Template)
if err == nil { if err == nil {
logrus.Infof("Using containerd template at %s", cfg.Containerd.Template) logrus.Infof("Using containerd template at %s", cfg.Containerd.Template)
......
package containerd
import (
"github.com/opencontainers/selinux/go-selinux"
)
const (
SELinuxContextType = "container_runtime_t"
)
func selinuxStatus() (bool, bool, error) {
if !selinux.GetEnabled() {
return false, false, nil
}
label, err := selinux.CurrentLabel()
if err != nil {
return true, false, err
}
ctx, err := selinux.NewContext(label)
if err != nil {
return true, false, err
}
return true, ctx["type"] == SELinuxContextType, nil
}
package netpol
import (
"context"
daemonconfig "github.com/rancher/k3s/pkg/daemons/config"
)
func Run(ctx context.Context, nodeConfig *daemonconfig.Node) error {
panic("Netpol is not supported on windows ensure to pass --disable-network-policy")
}
// +build !windows
package netpol package netpol
import ( import (
......
// Apache License v2.0 (copyright Cloud Native Labs & Rancher Labs) // Apache License v2.0 (copyright Cloud Native Labs & Rancher Labs)
// - modified from https://github.com/cloudnativelabs/kube-router/blob/d6f9f31a7b/pkg/controllers/netpol/network_policy_controller.go // - modified from https://github.com/cloudnativelabs/kube-router/blob/d6f9f31a7b/pkg/controllers/netpol/network_policy_controller.go
// +build !windows
package netpol package netpol
import ( import (
......
// Apache License v2.0 (copyright Cloud Native Labs & Rancher Labs) // Apache License v2.0 (copyright Cloud Native Labs & Rancher Labs)
// - modified from https://github.com/cloudnativelabs/kube-router/tree/d6f9f31a7b/pkg/utils // - modified from https://github.com/cloudnativelabs/kube-router/tree/d6f9f31a7b/pkg/utils
// +build !windows
package netpol package netpol
import ( import (
......
// +build !windows
package syssetup package syssetup
import ( import (
......
package syssetup
func Configure() {}
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
type ContainerdConfig struct { type ContainerdConfig struct {
NodeConfig *config.Node NodeConfig *config.Node
IsRunningInUserNS bool IsRunningInUserNS bool
SELinuxEnabled bool
PrivateRegistryConfig *Registry PrivateRegistryConfig *Registry
} }
...@@ -20,6 +21,7 @@ const ContainerdConfigTemplate = ` ...@@ -20,6 +21,7 @@ const ContainerdConfigTemplate = `
[plugins.cri] [plugins.cri]
stream_server_address = "127.0.0.1" stream_server_address = "127.0.0.1"
stream_server_port = "10010" stream_server_port = "10010"
enable_selinux = {{ .SELinuxEnabled }}
{{- if .IsRunningInUserNS }} {{- if .IsRunningInUserNS }}
disable_cgroup = true disable_cgroup = true
......
...@@ -28,6 +28,7 @@ type Agent struct { ...@@ -28,6 +28,7 @@ type Agent struct {
Rootless bool Rootless bool
RootlessAlreadyUnshared bool RootlessAlreadyUnshared bool
WithNodeID bool WithNodeID bool
DisableSELinux bool
AgentShared AgentShared
ExtraKubeletArgs cli.StringSlice ExtraKubeletArgs cli.StringSlice
ExtraKubeProxyArgs cli.StringSlice ExtraKubeProxyArgs cli.StringSlice
...@@ -127,6 +128,12 @@ var ( ...@@ -127,6 +128,12 @@ var (
Usage: "(agent/node) Registering and starting kubelet with set of labels", Usage: "(agent/node) Registering and starting kubelet with set of labels",
Value: &AgentConfig.Labels, Value: &AgentConfig.Labels,
} }
DisableSELinuxFlag = cli.BoolFlag{
Name: "disable-selinux",
Usage: "(agent/node) Disable SELinux in containerd if currently enabled",
Hidden: true,
Destination: &AgentConfig.DisableSELinux,
}
) )
func NewAgentCommand(action func(ctx *cli.Context) error) cli.Command { func NewAgentCommand(action func(ctx *cli.Context) error) cli.Command {
...@@ -169,6 +176,7 @@ func NewAgentCommand(action func(ctx *cli.Context) error) cli.Command { ...@@ -169,6 +176,7 @@ func NewAgentCommand(action func(ctx *cli.Context) error) cli.Command {
NodeLabels, NodeLabels,
NodeTaints, NodeTaints,
DockerFlag, DockerFlag,
DisableSELinuxFlag,
CRIEndpointFlag, CRIEndpointFlag,
PauseImageFlag, PauseImageFlag,
PrivateRegistryFlag, PrivateRegistryFlag,
......
...@@ -216,6 +216,7 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command { ...@@ -216,6 +216,7 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
NodeLabels, NodeLabels,
NodeTaints, NodeTaints,
DockerFlag, DockerFlag,
DisableSELinuxFlag,
CRIEndpointFlag, CRIEndpointFlag,
PauseImageFlag, PauseImageFlag,
PrivateRegistryFlag, PrivateRegistryFlag,
......
...@@ -25,6 +25,7 @@ type Node struct { ...@@ -25,6 +25,7 @@ type Node struct {
Docker bool Docker bool
ContainerRuntimeEndpoint string ContainerRuntimeEndpoint string
NoFlannel bool NoFlannel bool
DisableSELinux bool
FlannelBackend string FlannelBackend string
FlannelConf string FlannelConf string
FlannelConfOverride bool FlannelConfOverride bool
......
...@@ -16,6 +16,7 @@ const ( ...@@ -16,6 +16,7 @@ const (
NodeArgsAnnotation = "k3s.io/node-args" NodeArgsAnnotation = "k3s.io/node-args"
NodeEnvAnnotation = "k3s.io/node-env" NodeEnvAnnotation = "k3s.io/node-env"
NodeConfigHashAnnotation = "k3s.io/node-config-hash" NodeConfigHashAnnotation = "k3s.io/node-config-hash"
OmittedValue = "********"
) )
func getNodeArgs() (string, error) { func getNodeArgs() (string, error) {
...@@ -31,7 +32,7 @@ func getNodeArgs() (string, error) { ...@@ -31,7 +32,7 @@ func getNodeArgs() (string, error) {
for i, arg := range nodeArgsList { for i, arg := range nodeArgsList {
if isSecret(arg) { if isSecret(arg) {
if i+1 < len(nodeArgsList) { if i+1 < len(nodeArgsList) {
nodeArgsList[i+1] = "" nodeArgsList[i+1] = OmittedValue
} }
} }
} }
...@@ -52,7 +53,7 @@ func getNodeEnv() (string, error) { ...@@ -52,7 +53,7 @@ func getNodeEnv() (string, error) {
} }
for key := range k3sEnv { for key := range k3sEnv {
if isSecret(key) { if isSecret(key) {
k3sEnv[key] = "" k3sEnv[key] = OmittedValue
} }
} }
k3sEnvJSON, err := json.Marshal(k3sEnv) k3sEnvJSON, err := json.Marshal(k3sEnv)
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"strings" "strings"
"github.com/rancher/k3s/pkg/token" "github.com/rancher/k3s/pkg/token"
"github.com/rancher/k3s/pkg/util"
) )
type entry struct { type entry struct {
...@@ -141,7 +142,7 @@ func writePasswords(passwdFile string, records [][]string) error { ...@@ -141,7 +142,7 @@ func writePasswords(passwdFile string, records [][]string) error {
} }
defer out.Close() defer out.Close()
if err := out.Chmod(0600); err != nil { if err := util.SetFileModeForFile(out, 0600); err != nil {
return err return err
} }
......
// +build !windows
package rootless package rootless
import ( import (
......
// +build !windows
package rootless package rootless
import ( import (
......
package rootless
func Rootless(stateDir string) error {
panic("Rootless not supported on windows")
}
// +build !windows
package rootlessports package rootlessports
import ( import (
......
package rootlessports
import (
"context"
coreClients "github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1"
)
func Register(ctx context.Context, serviceController coreClients.ServiceController, httpsPort int) error {
panic("Rootless is not supported on windows")
}
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"github.com/rancher/k3s/pkg/rootlessports" "github.com/rancher/k3s/pkg/rootlessports"
"github.com/rancher/k3s/pkg/servicelb" "github.com/rancher/k3s/pkg/servicelb"
"github.com/rancher/k3s/pkg/static" "github.com/rancher/k3s/pkg/static"
"github.com/rancher/k3s/pkg/util"
v1 "github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1" v1 "github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1"
"github.com/rancher/wrangler/pkg/leader" "github.com/rancher/wrangler/pkg/leader"
"github.com/rancher/wrangler/pkg/resolvehome" "github.com/rancher/wrangler/pkg/resolvehome"
...@@ -263,12 +264,12 @@ func writeKubeConfig(certs string, config *Config) error { ...@@ -263,12 +264,12 @@ func writeKubeConfig(certs string, config *Config) error {
if config.ControlConfig.KubeConfigMode != "" { if config.ControlConfig.KubeConfigMode != "" {
mode, err := strconv.ParseInt(config.ControlConfig.KubeConfigMode, 8, 0) mode, err := strconv.ParseInt(config.ControlConfig.KubeConfigMode, 8, 0)
if err == nil { if err == nil {
os.Chmod(kubeConfig, os.FileMode(mode)) util.SetFileModeForPath(kubeConfig, os.FileMode(mode))
} else { } else {
logrus.Errorf("failed to set %s to mode %s: %v", kubeConfig, os.FileMode(mode), err) logrus.Errorf("failed to set %s to mode %s: %v", kubeConfig, os.FileMode(mode), err)
} }
} else { } else {
os.Chmod(kubeConfig, os.FileMode(0600)) util.SetFileModeForPath(kubeConfig, os.FileMode(0600))
} }
if kubeConfigSymlink != kubeConfig { if kubeConfigSymlink != kubeConfig {
......
// +build !windows
package util
import (
"os"
)
func SetFileModeForPath(name string, mode os.FileMode) error {
return os.Chmod(name, mode)
}
func SetFileModeForFile(file *os.File, mode os.FileMode) error {
return file.Chmod(mode)
}
package util
import (
"os"
)
func SetFileModeForPath(name string, mode os.FileMode) error {
return nil
}
func SetFileModeForFile(file *os.File, mode os.FileMode) error {
return nil
}
...@@ -46,12 +46,20 @@ STATIC_SQLITE=" ...@@ -46,12 +46,20 @@ STATIC_SQLITE="
-extldflags '-static -lm -ldl -lz -lpthread $DQLITE_STATIC_SQLITE' -extldflags '-static -lm -ldl -lz -lpthread $DQLITE_STATIC_SQLITE'
" "
TAGS="ctrd apparmor seccomp no_btrfs netcgo osusergo providerless $DQLITE_TAGS" TAGS="ctrd apparmor seccomp no_btrfs netcgo osusergo providerless $DQLITE_TAGS"
RUNC_TAGS="apparmor seccomp"
RUNC_STATIC="static"
if [ "$SELINUX" = "true" ]; then
TAGS="$TAGS selinux"
RUNC_TAGS="$RUNC_TAGS selinux"
fi
if [ "$STATIC_BUILD" != "true" ]; then if [ "$STATIC_BUILD" != "true" ]; then
STATIC=" STATIC="
" "
STATIC_SQLITE=" STATIC_SQLITE="
" "
RUNC_STATIC=""
else else
TAGS="static_build libsqlite3 $TAGS" TAGS="static_build libsqlite3 $TAGS"
fi fi
...@@ -109,13 +117,16 @@ ln -s containerd ./bin/ctr ...@@ -109,13 +117,16 @@ ln -s containerd ./bin/ctr
# echo Building containerd # echo Building containerd
# CGO_ENABLED=0 go build -tags "$TAGS" -ldflags "$VERSIONFLAGS $LDFLAGS $STATIC" -o bin/containerd ./cmd/containerd/ # CGO_ENABLED=0 go build -tags "$TAGS" -ldflags "$VERSIONFLAGS $LDFLAGS $STATIC" -o bin/containerd ./cmd/containerd/
echo Building runc echo Building runc
make EXTRA_LDFLAGS="-w -s" BUILDTAGS="apparmor seccomp" -C ./vendor/github.com/opencontainers/runc static rm -f ./vendor/github.com/opencontainers/runc/runc
make EXTRA_LDFLAGS="-w -s" BUILDTAGS="$RUNC_TAGS" -C ./vendor/github.com/opencontainers/runc $RUNC_STATIC
cp -f ./vendor/github.com/opencontainers/runc/runc ./bin/runc cp -f ./vendor/github.com/opencontainers/runc/runc ./bin/runc
echo Building containerd-shim echo Building containerd-shim
rm -f ./vendor/github.com/containerd/containerd/bin/containerd-shim
make -C ./vendor/github.com/containerd/containerd bin/containerd-shim make -C ./vendor/github.com/containerd/containerd bin/containerd-shim
cp -f ./vendor/github.com/containerd/containerd/bin/containerd-shim ./bin/containerd-shim cp -f ./vendor/github.com/containerd/containerd/bin/containerd-shim ./bin/containerd-shim
echo Building containerd-shim-runc-v2 echo Building containerd-shim-runc-v2
rm -f ./vendor/github.com/containerd/containerd/bin/containerd-shim-runc-v2
make -C ./vendor/github.com/containerd/containerd bin/containerd-shim-runc-v2 make -C ./vendor/github.com/containerd/containerd bin/containerd-shim-runc-v2
cp -f ./vendor/github.com/containerd/containerd/bin/containerd-shim-runc-v2 ./bin/containerd-shim-runc-v2 cp -f ./vendor/github.com/containerd/containerd/bin/containerd-shim-runc-v2 ./bin/containerd-shim-runc-v2
#!/bin/sh
set -e
set -x
REPO="https://api.github.com/repos/rancher/k3s-upgrade/dispatches"
# send dispatch event to REPO
curl -XPOST -u "${PAT_USERNAME}:${PAT_TOKEN}" \
-H "Accept: application/vnd.github.everest-preview+json" \
-H "Content-Type: application/json" $REPO \
--data '{"event_type": "create_tag", "client_payload": {"tag":"'"$DRONE_TAG"'"}}'
\ No newline at end of file
#!/bin/bash
set -e -x
cd $(dirname $0)/..
ARCH=${DRONE_STAGE_ARCH:-$(arch)}
. ./scripts/version.sh
if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(\-[^\+]*)?\+k3s.+$ ]]; then
echo "k3s version $VERSION does not match regex for rpm upload"
exit 0
fi
TMPDIR=$(mktemp -d)
cleanup() {
exit_code=$?
trap - EXIT INT
rm -rf ${TMPDIR}
exit ${exit_code}
}
trap cleanup EXIT INT
export HOME=${TMPDIR}
BIN_SUFFIX=""
if [ ${ARCH} = aarch64 ] || [ ${ARCH} = arm64 ]; then
BIN_SUFFIX="-arm64"
elif [ ${ARCH} = armv7l ] || [ ${ARCH} = arm ]; then
BIN_SUFFIX="-armhf"
fi
# capture version of k3s
k3s_version=$(sed -E -e 's/^v([^-+]*).*$/\1/' <<< $VERSION)
# capture pre-release and metadata information of k3s
k3s_release=$(sed -E -e 's/\+k3s/+/; s/\+/-/g; s/^[^-]*//; s/^--/dev-/; s/-+/./g; s/^\.+//; s/\.+$//;' <<< $VERSION)
# k3s-selinux policy version needed for functionality
k3s_policyver=0.1-1
rpmbuild \
--define "k3s_version ${k3s_version}" \
--define "k3s_release ${k3s_release}" \
--define "k3s_policyver ${k3s_policyver}" \
--define "k3s_binary k3s${BIN_SUFFIX}" \
--define "_sourcedir ${PWD}" \
--define "_specdir ${PWD}" \
--define "_builddir ${PWD}" \
--define "_srcrpmdir ${PWD}" \
--define "_rpmdir ${PWD}/dist/rpm" \
--define "_buildrootdir ${PWD}/.rpm-build" \
-bb package/k3s.spec
if ! grep "BEGIN PGP PRIVATE KEY BLOCK" <<<"$PRIVATE_KEY"; then
echo "PRIVATE_KEY not defined, skipping rpm sign and upload"
exit 0
fi
cat <<\EOF >~/.rpmmacros
%_signature gpg
%_gpg_name ci@rancher.com
EOF
gpg --import - <<<"$PRIVATE_KEY"
expect <<EOF
set timeout 60
spawn sh -c "rpmsign --addsign dist/rpm/**/k3s-*.rpm"
expect "Enter pass phrase:"
send -- "$PRIVATE_KEY_PASS_PHRASE\r"
expect eof
lassign [wait] _ _ _ code
exit \$code
EOF
if [ -z "$AWS_S3_BUCKET" ]; then
echo "AWS_S3_BUCKET skipping rpm upload"
exit 0
fi
rpm-s3 --bucket $AWS_S3_BUCKET dist/rpm/**/k3s-*.rpm
#!/bin/bash
set -ve
apk add -q -f curl libc6-compat tzdata
download_go
download_dqlite
# ---
cat <<EOF >/etc/profile.d/build.sh
export SELINUX=true
export DQLITE=true
export STATIC_BUILD=true
EOF
. /etc/profile.d/build.sh
# ---
. /tmp/docker-run
# ---
go get -u github.com/go-delve/delve/cmd/dlv
# ---
cat <<EOF >/etc/profile.d/docker.sh
export DOCKER_HOST=tcp://10.0.2.2:2375
EOF
. /etc/profile.d/docker.sh
# ---
(
if ! docker version --format '{{.Server.Version}}' >/tmp/docker-server-version; then
echo "WARNING: Unable to connect to the docker socket, to enable docker in vagrant run the following command on the host:"
echo "docker run -d -v /var/run/docker.sock:/var/run/docker.sock -p 127.0.0.1:2375:2375 alpine/socat TCP-LISTEN:2375,fork UNIX-CONNECT:/var/run/docker.sock"
else
echo "Using host docker server v$(cat /tmp/docker-server-version)"
fi
)
\ No newline at end of file
#!/bin/bash
set -e -x
TMPDIR=$(mktemp -d)
cleanup() {
exit_code=$?
trap - EXIT INT
rm -rf ${TMPDIR}
exit ${exit_code}
}
trap cleanup EXIT INT
export HOME=${TMPDIR}
gpg --batch --gen-key - <<EOF
%echo Generating a default key
Key-Type: default
Subkey-Type: default
Name-Real: Rancher
Name-Comment: CI
Name-Email: ci@rancher.com
Expire-Date: 0
# Key-Length: 4096
# Subkey-Length: 4096
Passphrase: $PRIVATE_KEY_PASS_PHRASE
# %no-protection
# %no-ask-passphrase
# Do a commit here, so that we can later print "done" :-)
%commit
%echo done
EOF
gpg --armor --export ci@rancher.com >public.key
gpg --armor --export-secret-key ci@rancher.com >private.key
#!/bin/bash
set -ve
download_go
# ---
cat <<EOF >/etc/profile.d/build.sh
export SELINUX=true
# export DQLITE=true
# export STATIC_BUILD=true
EOF
. /etc/profile.d/build.sh
# ---
sed -E 's|apk( -U)?( --no-cache)?( --repository [^ ]*)? add|yum install -y|g' -i /tmp/docker-run
sed -E 's/-dev/-devel/g' -i /tmp/docker-run
. /tmp/docker-run
# ---
go get -u github.com/go-delve/delve/cmd/dlv
# ---
# docker install instructions slightly changed from https://kubernetes.io/docs/setup/production-environment/container-runtimes/
# default "exec-opts": ["native.cgroupdriver=cgroupfs"], and set "selinux-enabled": true
yum remove -y docker docker-common
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum update -y && yum install -y containerd.io-1.2.10 docker-ce-19.03.4 docker-ce-cli-19.03.4
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"selinux-enabled": true,
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF
# ---
systemctl daemon-reload
systemctl disable --now firewalld
systemctl disable --now docker
# ---
# set selinux to permissive for dev & testing purposes only
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
#!/bin/bash
set -e -x
yum install -y git expect yum-utils rpm-build rpm-sign python-deltarpm epel-release
yum install -y python2-pip
pip install git+git://github.com/Voronenko/rpm-s3.git@5695c6ad9a08548141d3713328e1bd3f533d137e
#!/bin/bash
set -ve
download_go
# ---
cat <<EOF >/etc/profile.d/build.sh
export SELINUX=true
# export DQLITE=true
# export STATIC_BUILD=true
EOF
. /etc/profile.d/build.sh
# ---
apt-get install -y \
build-essential \
pkg-config \
libseccomp-dev \
libsqlite3-dev \
libselinux1-dev \
zlib1g-dev \
# ---
sed -E 's|apk( -U)?( --no-cache)?( --repository [^ ]*)? add|apt-get install -y|g' -i /tmp/docker-run
. /tmp/docker-run
# ---
go get -u github.com/go-delve/delve/cmd/dlv
# ---
#!/bin/bash #!/bin/bash
set -ve set -ve
cd $(dirname $0)/.. PROVISION="scripts/provision/$BOX/vagrant"
if [ ! -f /etc/vagrant_box_build_time ]; then if [ ! -f /etc/vagrant_box_build_time ]; then
echo "This script should only be called during vagrant provisioning" echo "This script should only be called during vagrant provisioning"
exit 1 exit 1
fi fi
ARCH=amd64
if [[ $HOME == /go/* ]]; then if [[ $HOME == /go/* ]]; then
echo "Must not launch vagrant from /go/" echo "Must not launch vagrant from /go/"
exit 1 exit 1
fi fi
cd
# --- Default to root user for vagrant ssh
cat <<\EOF >/etc/profile.d/root.sh
[ $EUID -ne 0 ] && exec sudo -i
EOF
# --- Setup go version
if [ -z "${GOPATH}" ]; then if [ -z "${GOPATH}" ]; then
GOPATH=$(realpath $HOME/../../../..) GOPATH=$(realpath $HOME/../../../..)
echo "WARNING: Assuming GOPATH=$GOPATH" echo "WARNING: Assuming GOPATH=$GOPATH"
else else
echo "Using parent GOPATH=$GOPATH" echo "Using parent GOPATH=$GOPATH"
fi fi
goversion=$(grep "^FROM " Dockerfile.dapper | sed -e 's/^FROM golang:\(.*\)-.*/\1/')
if [ -z "$goversion" ]; then # --- Setup basic env
echo "Cannot find version of go to fetch" cat <<EOF >/etc/profile.d/env.sh
exit 1 export ARCH=amd64
fi export GO111MODULE=off
export GOPATH="$GOPATH"
echo "Installing go $goversion" export PATH=/usr/local/bin:$PATH:/usr/local/go/bin:$GOPATH/bin
apk add -q -f curl libc6-compat tzdata export HOME="$HOME" && cd
curl -sL https://storage.googleapis.com/golang/go${goversion}.linux-${ARCH}.tar.gz | tar -xzf - -C /usr/local
# ---
cat <<EOF >/etc/profile.d/build.sh
export STATIC_BUILD=true
EOF
# ---
cat <<EOF >/etc/profile.d/go.sh
export GOPATH=$GOPATH
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
EOF EOF
. /etc/profile.d/go.sh . /etc/profile.d/env.sh
# ---
# --- Clean go cache
rm -rf .cache/go-build || true
# --- Set color prompt
sed -i 's|:/bin/ash$|:/bin/bash|g' /etc/passwd sed -i 's|:/bin/ash$|:/bin/bash|g' /etc/passwd
cat <<\EOF >/etc/profile.d/color.sh cat <<\EOF >/etc/profile.d/color.sh
alias ls='ls --color=auto' alias ls='ls --color=auto'
export PS1='\033[31m[ \033[90m\D{%F %T}\033[31m ]\n\[\033[36m\]\u\[\033[m\]🐮\[\033[32m\]\h:\[\033[33;1m\]\w\[\033[m\]$ ' export PS1='\033[31m[ \033[90m\D{%F 🐮 %T}\033[31m ]\n\[\033[36m\]\u\[\033[m\]@\[\033[32m\]\h\[\033[35m\]:\[\033[33;1m\]\w\[\033[m\]\$ '
EOF EOF
# ---
# --- Setup install script from docker run commands
mkdir -p ${GOPATH}/bin mkdir -p ${GOPATH}/bin
mkdir -p /go mkdir -p /go
ln -s $GOPATH/bin /go/bin ln -sf $GOPATH/bin /go/bin
sed ':a;N;$!ba;s/\\\n/ /g' <Dockerfile.dapper | grep '^RUN ' | sed -e 's/^RUN //' >/tmp/docker-run sed ':a;N;$!ba;s/\\\n/ /g' <Dockerfile.dapper | grep '^RUN ' | sed -e 's/^RUN //' >/tmp/docker-run
export BINDIR=/go/bin export BINDIR=/go/bin
export GOPATH=/go export GOPATH=/go
export HOME=/tmp && cd export HOME=/tmp
. /tmp/docker-run
cd /go # --- Add k3s motd
go get github.com/rancher/trash cat <<\EOF >/etc/motd
rm -rf /go
cd
# ---
cat <<EOF >/etc/profile.d/docker.sh
export DOCKER_HOST=tcp://10.0.2.2:2375
EOF
. /etc/profile.d/docker.sh
# ---
cat <<\EOF >>/etc/motd
, , , ,
,-----------|'------'| |\ ____ ,-----------|'------'| |\ ____
/. '-'@ o|-' | | /___ \ /. '-'@ o|-' | | /___ \
...@@ -75,11 +67,35 @@ cat <<\EOF >>/etc/motd ...@@ -75,11 +67,35 @@ cat <<\EOF >>/etc/motd
\__|' \__|' |_|\_\_____/____/ \__|' \__|' |_|\_\_____/____/
EOF EOF
# ---
set +v # --- Utility function to download go
if ! docker version --format '{{.Server.Version}}' >/tmp/docker-server-version; then download_go() {
echo "WARNING: Unable to connect to the docker socket, to enable docker in vagrant run the following command on the host:" goversion=$(grep "^FROM " Dockerfile.dapper | sed -e 's/^FROM golang:\(.*\)-.*/\1/')
echo "docker run -d -v /var/run/docker.sock:/var/run/docker.sock -p 127.0.0.1:2375:2375 alpine/socat TCP-LISTEN:2375,fork UNIX-CONNECT:/var/run/docker.sock" if [ -z "$goversion" ]; then
else echo "Cannot find version of go to fetch"
echo "Using host docker server v$(cat /tmp/docker-server-version)" return 1
fi
echo "Installing go $goversion"
curl -sL https://storage.googleapis.com/golang/go${goversion}.linux-${ARCH}.tar.gz | tar -xzf - -C /usr/local
}
# --- Utility function to download dqlite
download_dqlite() {
dqliteURL="https://github.com/$(grep dqlite-build Dockerfile.dapper | sed -e 's/^.*--from=\([^ ]*\).*$/\1/' -e 's|:|/releases/download/|')/dqlite-$ARCH.tgz"
if [ -z "$dqliteURL" ]; then
echo "Cannot find dqlite URL to fetch"
return 1
fi
mkdir -p /usr/src/
echo "Downloading DQLITE from $dqliteURL"
curl -sL $dqliteURL -o /usr/src/dqlite.tgz
}
# --- Run vagrant provision script if available
if [ ! -f "${PROVISION}" ]; then
echo 'WARNING: Unable to execute provision script "${PROVISION}"'
exit
fi fi
echo "running '${PROVISION}'..." && \
. ${PROVISION} && \
echo "finished '${PROVISION}'!"
...@@ -13,19 +13,18 @@ mkdir -p $artifacts ...@@ -13,19 +13,18 @@ mkdir -p $artifacts
# --- # ---
[ "$ARCH" = 'arm' ] && \
early-exit "Skipping sonobuoy, images not available for $ARCH."
E2E_OUTPUT=$artifacts test-run-sonobuoy E2E_OUTPUT=$artifacts test-run-sonobuoy
# --- # ---
if [ "$DRONE_BUILD_EVENT" = 'tag' ]; then [ "$DRONE_BUILD_EVENT" = 'tag' ] && \
printf "\033[33mSkipping remaining tests on tag.\033[m\n" early-exit 'Skipping remaining tests on tag.'
exit 0
fi
if [ "$ARCH" != 'amd64' ]; then [ "$ARCH" != 'amd64' ] && \
printf "\033[33mSkipping remaining tests, images not available for $ARCH.\033[m\n" early-exit "Skipping remaining tests, images not available for $ARCH."
exit 0
fi
# --- # ---
......
...@@ -437,6 +437,14 @@ export -f provision-cluster ...@@ -437,6 +437,14 @@ export -f provision-cluster
# --- # ---
early-exit() {
printf "\033[33m$1\033[m\n"
exit $2
}
export -f early-exit
# ---
run-test() { run-test() {
export PROVISION_LOCK=$(mktemp) export PROVISION_LOCK=$(mktemp)
./scripts/test-runner $@ & ./scripts/test-runner $@ &
...@@ -454,27 +462,27 @@ export -f run-test ...@@ -454,27 +462,27 @@ export -f run-test
# --- # ---
e2e-test() { e2e-test() {
local label=$label local label=$label
if [ -n "$LABEL_SUFFIX" ]; then if [ -n "$LABEL_SUFFIX" ]; then
label="$label-$LABEL_SUFFIX" label="$label-$LABEL_SUFFIX"
fi fi
local logOutput= local logOutput=
if [ -n "$E2E_OUTPUT" ]; then if [ -n "$E2E_OUTPUT" ]; then
logOutput=$E2E_OUTPUT/$logName logOutput=$E2E_OUTPUT/$logName
fi fi
LABEL=$label LOG_OUTPUT=$logOutput run-test $@ LABEL=$label LOG_OUTPUT=$logOutput run-test $@
} }
# --- # ---
run-e2e-tests() { run-e2e-tests() {
label=PARALLEL \ label=PARALLEL \
logName=e2e-STATUS-${ARCH}-parallel.log \ logName=e2e-STATUS-${ARCH}-parallel.log \
e2e-test ${sonobuoyParallelArgs[@]} e2e-test ${sonobuoyParallelArgs[@]}
label=SERIAL \ label=SERIAL \
logName=e2e-STATUS-${ARCH}-serial.log \ logName=e2e-STATUS-${ARCH}-serial.log \
e2e-test ${sonobuoySerialArgs[@]} e2e-test ${sonobuoySerialArgs[@]}
} }
export -f run-e2e-tests export -f run-e2e-tests
......
#!/bin/bash #!/bin/bash
all_services=(
coredns
local-path-provisioner
metrics-server
traefik
)
export NUM_SERVERS=1 export NUM_SERVERS=1
export NUM_AGENTS=1 export NUM_AGENTS=1
export SERVER_ARGS='--no-deploy=traefik,coredns,local-storage,metrics-server' export WAIT_SERVICES="${all_services[@]}"
start-test() { start-test() {
docker exec $(cat $TEST_DIR/servers/1/metadata/name) check-config || true docker exec $(cat $TEST_DIR/servers/1/metadata/name) check-config || true
verify-valid-versions $(cat $TEST_DIR/servers/1/metadata/name) verify-valid-versions $(cat $TEST_DIR/servers/1/metadata/name)
verify-airgap-images $(cat $TEST_DIR/{servers,agents}/*/metadata/name)
} }
export -f start-test export -f start-test
# -- check for changes to the airgap image list
verify-airgap-images() {
local airgap_image_list='scripts/airgap/image-list.txt'
for name in $@; do
docker exec $name crictl images -o json \
| jq -r '.images[].repoTags[0] | select(. != null)'
done | sort -u >$airgap_image_list.tmp
if ! diff $airgap_image_list{,.tmp}; then
echo '[ERROR] Failed airgap image check'
return 1
fi
}
export -f verify-airgap-images
# --- create a basic cluster and check for valid versions # --- create a basic cluster and check for valid versions
LABEL=BASICS run-test LABEL=BASICS run-test
#!/bin/bash #!/bin/bash
ARCH=${ARCH:-$(go env GOARCH)}
SUFFIX="-${ARCH}"
GIT_TAG=$DRONE_TAG
TREE_STATE=clean TREE_STATE=clean
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then COMMIT=$DRONE_COMMIT
DIRTY="-dirty"
TREE_STATE=dirty
fi
COMMIT=$(git log -n3 --pretty=format:"%H %ae" | grep -v ' drone@localhost$' | cut -f1 -d\ | head -1) if [ -d .git ]; then
if [ -z "${COMMIT}" ]; then if [ -z "$GIT_TAG" ]; then
COMMIT=$(git rev-parse HEAD) GIT_TAG=$(git tag -l --contains HEAD | head -n 1)
fi fi
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
GIT_TAG=${DRONE_TAG:-$(git tag -l --contains HEAD | head -n 1)} DIRTY="-dirty"
TREE_STATE=dirty
fi
ARCH=$(go env GOARCH) COMMIT=$(git log -n3 --pretty=format:"%H %ae" | grep -v ' drone@localhost$' | cut -f1 -d\ | head -1)
SUFFIX="-${ARCH}" if [ -z "${COMMIT}" ]; then
COMMIT=$(git rev-parse HEAD || true)
fi
fi
VERSION_CONTAINERD=$(grep github.com/containerd/containerd go.mod | head -n1 | awk '{print $4}') VERSION_CONTAINERD=$(grep github.com/containerd/containerd go.mod | head -n1 | awk '{print $4}')
if [ -z "$VERSION_CONTAINERD" ]; then if [ -z "$VERSION_CONTAINERD" ]; then
......
...@@ -36,6 +36,7 @@ import ( ...@@ -36,6 +36,7 @@ import (
prototypes "github.com/gogo/protobuf/types" prototypes "github.com/gogo/protobuf/types"
ver "github.com/opencontainers/image-spec/specs-go" ver "github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
...@@ -242,7 +243,17 @@ func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...N ...@@ -242,7 +243,17 @@ func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...N
if err != nil { if err != nil {
return nil, err return nil, err
} }
spec, err := c.Spec(ctx)
if err != nil {
return nil, err
}
for _, m := range mounts { for _, m := range mounts {
if spec.Linux != nil && spec.Linux.MountLabel != "" {
context := label.FormatMountLabel("", spec.Linux.MountLabel)
if context != "" {
m.Options = append(m.Options, context)
}
}
request.Rootfs = append(request.Rootfs, &types.Mount{ request.Rootfs = append(request.Rootfs, &types.Mount{
Type: m.Type, Type: m.Type,
Source: m.Source, Source: m.Source,
......
...@@ -39,6 +39,7 @@ import ( ...@@ -39,6 +39,7 @@ import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
imagespec "github.com/opencontainers/image-spec/specs-go/v1" imagespec "github.com/opencontainers/image-spec/specs-go/v1"
runtimespec "github.com/opencontainers/runtime-spec/specs-go" runtimespec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/net/context" "golang.org/x/net/context"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
...@@ -173,6 +174,18 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta ...@@ -173,6 +174,18 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
return nil, errors.Wrapf(err, "failed to generate container %q spec", id) return nil, errors.Wrapf(err, "failed to generate container %q spec", id)
} }
meta.ProcessLabel = spec.Process.SelinuxLabel
if config.GetLinux().GetSecurityContext().GetPrivileged() {
// If privileged don't set the SELinux label but still record it on the container so
// the unused MCS label can be release later
spec.Process.SelinuxLabel = ""
}
defer func() {
if retErr != nil {
_ = label.ReleaseLabel(spec.Process.SelinuxLabel)
}
}()
log.G(ctx).Debugf("Container %q spec: %#+v", id, spew.NewFormatter(spec)) log.G(ctx).Debugf("Container %q spec: %#+v", id, spew.NewFormatter(spec))
// Set snapshotter before any other options. // Set snapshotter before any other options.
...@@ -324,7 +337,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta ...@@ -324,7 +337,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxPid uint32, config *runtime.ContainerConfig, func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxPid uint32, config *runtime.ContainerConfig,
sandboxConfig *runtime.PodSandboxConfig, imageConfig *imagespec.ImageConfig, extraMounts []*runtime.Mount, sandboxConfig *runtime.PodSandboxConfig, imageConfig *imagespec.ImageConfig, extraMounts []*runtime.Mount,
ociRuntime config.Runtime) (*runtimespec.Spec, error) { ociRuntime config.Runtime) (retSpec *runtimespec.Spec, retErr error) {
specOpts := []oci.SpecOpts{ specOpts := []oci.SpecOpts{
customopts.WithoutRunMount, customopts.WithoutRunMount,
...@@ -366,11 +379,27 @@ func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxP ...@@ -366,11 +379,27 @@ func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxP
specOpts = append(specOpts, oci.WithEnv(env)) specOpts = append(specOpts, oci.WithEnv(env))
securityContext := config.GetLinux().GetSecurityContext() securityContext := config.GetLinux().GetSecurityContext()
selinuxOpt := securityContext.GetSelinuxOptions() labelOptions := toLabel(securityContext.GetSelinuxOptions())
processLabel, mountLabel, err := initSelinuxOpts(selinuxOpt) if len(labelOptions) == 0 {
// Use pod level SELinux config
if sandbox, err := c.sandboxStore.Get(sandboxID); err == nil {
labelOptions, err = label.DupSecOpt(sandbox.ProcessLabel)
if err != nil {
return nil, err
}
}
}
processLabel, mountLabel, err := label.InitLabels(labelOptions)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to init selinux options %+v", securityContext.GetSelinuxOptions()) return nil, errors.Wrapf(err, "failed to init selinux options %+v", securityContext.GetSelinuxOptions())
} }
defer func() {
if retErr != nil {
_ = label.ReleaseLabel(processLabel)
}
}()
specOpts = append(specOpts, customopts.WithMounts(c.os, config, extraMounts, mountLabel)) specOpts = append(specOpts, customopts.WithMounts(c.os, config, extraMounts, mountLabel))
if !c.config.DisableProcMount { if !c.config.DisableProcMount {
......
...@@ -298,47 +298,55 @@ func (c *criService) ensureImageExists(ctx context.Context, ref string, config * ...@@ -298,47 +298,55 @@ func (c *criService) ensureImageExists(ctx context.Context, ref string, config *
return &newImage, nil return &newImage, nil
} }
func initSelinuxOpts(selinuxOpt *runtime.SELinuxOption) (string, string, error) { func toLabel(selinuxOptions *runtime.SELinuxOption) (labels []string) {
if selinuxOpt == nil { if selinuxOptions == nil {
return "", "", nil return nil
} }
// Should ignored selinuxOpts if they are incomplete. if selinuxOptions.User != "" {
if selinuxOpt.GetUser() == "" || labels = append(labels, "user:"+selinuxOptions.User)
selinuxOpt.GetRole() == "" ||
selinuxOpt.GetType() == "" {
return "", "", nil
} }
if selinuxOptions.Role != "" {
// make sure the format of "level" is correct. labels = append(labels, "role:"+selinuxOptions.Role)
ok, err := checkSelinuxLevel(selinuxOpt.GetLevel()) }
if err != nil || !ok { if selinuxOptions.Type != "" {
return "", "", err labels = append(labels, "type:"+selinuxOptions.Type)
}
if selinuxOptions.Level != "" {
labels = append(labels, "level:"+selinuxOptions.Level)
} }
labelOpts := fmt.Sprintf("%s:%s:%s:%s", return
selinuxOpt.GetUser(), }
selinuxOpt.GetRole(),
selinuxOpt.GetType(),
selinuxOpt.GetLevel())
options, err := label.DupSecOpt(labelOpts) func initLabelsFromOpt(selinuxOpts *runtime.SELinuxOption) (string, string, error) {
if err != nil { return initLabels(toLabel(selinuxOpts))
return "", "", err }
func initLabels(options []string) (string, string, error) {
for _, opt := range options {
if strings.HasPrefix(opt, "level:") {
if err := checkSelinuxLevel(strings.TrimPrefix(opt, "level:")); err != nil {
return "", "", err
}
}
} }
return label.InitLabels(options) return label.InitLabels(options)
} }
func checkSelinuxLevel(level string) (bool, error) { func checkSelinuxLevel(level string) error {
if len(level) == 0 { if len(level) == 0 {
return true, nil return nil
} }
matched, err := regexp.MatchString(`^s\d(-s\d)??(:c\d{1,4}((.c\d{1,4})?,c\d{1,4})*(.c\d{1,4})?(,c\d{1,4}(.c\d{1,4})?)*)?$`, level) matched, err := regexp.MatchString(`^s\d(-s\d)??(:c\d{1,4}((.c\d{1,4})?,c\d{1,4})*(.c\d{1,4})?(,c\d{1,4}(.c\d{1,4})?)*)?$`, level)
if err != nil || !matched { if err != nil {
return false, errors.Wrapf(err, "the format of 'level' %q is not correct", level) return errors.Wrapf(err, "the format of 'level' %q is not correct", level)
}
if !matched {
return fmt.Errorf("the format of 'level' %q is not correct", level)
} }
return true, nil return nil
} }
// isInCRIMounts checks whether a destination is in CRI mount list. // isInCRIMounts checks whether a destination is in CRI mount list.
......
...@@ -34,6 +34,7 @@ import ( ...@@ -34,6 +34,7 @@ import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
imagespec "github.com/opencontainers/image-spec/specs-go/v1" imagespec "github.com/opencontainers/image-spec/specs-go/v1"
runtimespec "github.com/opencontainers/runtime-spec/specs-go" runtimespec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/net/context" "golang.org/x/net/context"
...@@ -158,6 +159,18 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox ...@@ -158,6 +159,18 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
return nil, errors.Wrap(err, "failed to generate sandbox container spec") return nil, errors.Wrap(err, "failed to generate sandbox container spec")
} }
log.G(ctx).Debugf("Sandbox container %q spec: %#+v", id, spew.NewFormatter(spec)) log.G(ctx).Debugf("Sandbox container %q spec: %#+v", id, spew.NewFormatter(spec))
sandbox.ProcessLabel = spec.Process.SelinuxLabel
defer func() {
if retErr != nil {
_ = label.ReleaseLabel(sandbox.ProcessLabel)
}
}()
if securityContext.GetPrivileged() {
// If privileged don't set selinux label, but we still record the MCS label so that
// the unused label can be freed later.
spec.Process.SelinuxLabel = ""
}
var specOpts []oci.SpecOpts var specOpts []oci.SpecOpts
userstr, err := generateUserString( userstr, err := generateUserString(
...@@ -328,7 +341,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox ...@@ -328,7 +341,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
} }
func (c *criService) generateSandboxContainerSpec(id string, config *runtime.PodSandboxConfig, func (c *criService) generateSandboxContainerSpec(id string, config *runtime.PodSandboxConfig,
imageConfig *imagespec.ImageConfig, nsPath string, runtimePodAnnotations []string) (*runtimespec.Spec, error) { imageConfig *imagespec.ImageConfig, nsPath string, runtimePodAnnotations []string) (retSpec *runtimespec.Spec, retErr error) {
// Creates a spec Generator with the default spec. // Creates a spec Generator with the default spec.
// TODO(random-liu): [P1] Compare the default settings with docker and containerd default. // TODO(random-liu): [P1] Compare the default settings with docker and containerd default.
specOpts := []oci.SpecOpts{ specOpts := []oci.SpecOpts{
...@@ -403,11 +416,15 @@ func (c *criService) generateSandboxContainerSpec(id string, config *runtime.Pod ...@@ -403,11 +416,15 @@ func (c *criService) generateSandboxContainerSpec(id string, config *runtime.Pod
}, },
})) }))
selinuxOpt := securityContext.GetSelinuxOptions() processLabel, mountLabel, err := initLabelsFromOpt(securityContext.GetSelinuxOptions())
processLabel, mountLabel, err := initSelinuxOpts(selinuxOpt)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to init selinux options %+v", securityContext.GetSelinuxOptions()) return nil, errors.Wrapf(err, "failed to init selinux options %+v", securityContext.GetSelinuxOptions())
} }
defer func() {
if retErr != nil && processLabel != "" {
_ = label.ReleaseLabel(processLabel)
}
}()
supplementalGroups := securityContext.GetSupplementalGroups() supplementalGroups := securityContext.GetSupplementalGroups()
specOpts = append(specOpts, specOpts = append(specOpts,
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
"github.com/containerd/containerd" "github.com/containerd/containerd"
"github.com/containerd/containerd/plugin" "github.com/containerd/containerd/plugin"
"github.com/containerd/cri/pkg/store/label"
cni "github.com/containerd/go-cni" cni "github.com/containerd/go-cni"
runcapparmor "github.com/opencontainers/runc/libcontainer/apparmor" runcapparmor "github.com/opencontainers/runc/libcontainer/apparmor"
runcseccomp "github.com/opencontainers/runc/libcontainer/seccomp" runcseccomp "github.com/opencontainers/runc/libcontainer/seccomp"
...@@ -104,14 +105,15 @@ type criService struct { ...@@ -104,14 +105,15 @@ type criService struct {
// NewCRIService returns a new instance of CRIService // NewCRIService returns a new instance of CRIService
func NewCRIService(config criconfig.Config, client *containerd.Client) (CRIService, error) { func NewCRIService(config criconfig.Config, client *containerd.Client) (CRIService, error) {
var err error var err error
labels := label.NewStore()
c := &criService{ c := &criService{
config: config, config: config,
client: client, client: client,
apparmorEnabled: runcapparmor.IsEnabled() && !config.DisableApparmor, apparmorEnabled: runcapparmor.IsEnabled() && !config.DisableApparmor,
seccompEnabled: runcseccomp.IsEnabled(), seccompEnabled: runcseccomp.IsEnabled(),
os: osinterface.RealOS{}, os: osinterface.RealOS{},
sandboxStore: sandboxstore.NewStore(), sandboxStore: sandboxstore.NewStore(labels),
containerStore: containerstore.NewStore(), containerStore: containerstore.NewStore(labels),
imageStore: imagestore.NewStore(client), imageStore: imagestore.NewStore(client),
snapshotStore: snapshotstore.NewStore(), snapshotStore: snapshotstore.NewStore(),
sandboxNameIndex: registrar.NewRegistrar(), sandboxNameIndex: registrar.NewRegistrar(),
......
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
"sync" "sync"
"github.com/containerd/containerd" "github.com/containerd/containerd"
"github.com/containerd/cri/pkg/store/label"
"github.com/docker/docker/pkg/truncindex" "github.com/docker/docker/pkg/truncindex"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
...@@ -101,13 +102,15 @@ type Store struct { ...@@ -101,13 +102,15 @@ type Store struct {
lock sync.RWMutex lock sync.RWMutex
containers map[string]Container containers map[string]Container
idIndex *truncindex.TruncIndex idIndex *truncindex.TruncIndex
labels *label.Store
} }
// NewStore creates a container store. // NewStore creates a container store.
func NewStore() *Store { func NewStore(labels *label.Store) *Store {
return &Store{ return &Store{
containers: make(map[string]Container), containers: make(map[string]Container),
idIndex: truncindex.NewTruncIndex([]string{}), idIndex: truncindex.NewTruncIndex([]string{}),
labels: labels,
} }
} }
...@@ -119,6 +122,9 @@ func (s *Store) Add(c Container) error { ...@@ -119,6 +122,9 @@ func (s *Store) Add(c Container) error {
if _, ok := s.containers[c.ID]; ok { if _, ok := s.containers[c.ID]; ok {
return store.ErrAlreadyExist return store.ErrAlreadyExist
} }
if err := s.labels.Reserve(c.ProcessLabel); err != nil {
return err
}
if err := s.idIndex.Add(c.ID); err != nil { if err := s.idIndex.Add(c.ID); err != nil {
return err return err
} }
...@@ -165,6 +171,7 @@ func (s *Store) Delete(id string) { ...@@ -165,6 +171,7 @@ func (s *Store) Delete(id string) {
// So we need to return if there are error. // So we need to return if there are error.
return return
} }
s.labels.Release(s.containers[id].ProcessLabel)
s.idIndex.Delete(id) // nolint: errcheck s.idIndex.Delete(id) // nolint: errcheck
delete(s.containers, id) delete(s.containers, id)
} }
...@@ -61,6 +61,8 @@ type Metadata struct { ...@@ -61,6 +61,8 @@ type Metadata struct {
// StopSignal is the system call signal that will be sent to the container to exit. // StopSignal is the system call signal that will be sent to the container to exit.
// TODO(random-liu): Add integration test for stop signal. // TODO(random-liu): Add integration test for stop signal.
StopSignal string StopSignal string
// ProcessLabel is the SELinux process label for the container
ProcessLabel string
} }
// MarshalJSON encodes Metadata into bytes in json format. // MarshalJSON encodes Metadata into bytes in json format.
......
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package label
import (
"sync"
"github.com/opencontainers/selinux/go-selinux"
)
type Store struct {
sync.Mutex
levels map[string]int
Releaser func(string)
Reserver func(string)
}
func NewStore() *Store {
return &Store{
levels: map[string]int{},
Releaser: selinux.ReleaseLabel,
Reserver: selinux.ReserveLabel,
}
}
func (s *Store) Reserve(label string) error {
s.Lock()
defer s.Unlock()
context, err := selinux.NewContext(label)
if err != nil {
return err
}
level := context["level"]
// no reason to count empty
if level == "" {
return nil
}
if _, ok := s.levels[level]; !ok {
s.Reserver(label)
}
s.levels[level]++
return nil
}
func (s *Store) Release(label string) {
s.Lock()
defer s.Unlock()
context, err := selinux.NewContext(label)
if err != nil {
return
}
level := context["level"]
if level == "" {
return
}
count, ok := s.levels[level]
if !ok {
return
}
switch {
case count == 1:
s.Releaser(label)
delete(s.levels, level)
case count < 1:
delete(s.levels, level)
case count > 1:
s.levels[level] = count - 1
}
}
...@@ -61,6 +61,8 @@ type Metadata struct { ...@@ -61,6 +61,8 @@ type Metadata struct {
RuntimeHandler string RuntimeHandler string
// CNIresult resulting configuration for attached network namespace interfaces // CNIresult resulting configuration for attached network namespace interfaces
CNIResult *cni.CNIResult CNIResult *cni.CNIResult
// ProcessLabel is the SELinux process label for the container
ProcessLabel string
} }
// MarshalJSON encodes Metadata into bytes in json format. // MarshalJSON encodes Metadata into bytes in json format.
......
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
"sync" "sync"
"github.com/containerd/containerd" "github.com/containerd/containerd"
"github.com/containerd/cri/pkg/store/label"
"github.com/docker/docker/pkg/truncindex" "github.com/docker/docker/pkg/truncindex"
"github.com/containerd/cri/pkg/netns" "github.com/containerd/cri/pkg/netns"
...@@ -62,13 +63,15 @@ type Store struct { ...@@ -62,13 +63,15 @@ type Store struct {
lock sync.RWMutex lock sync.RWMutex
sandboxes map[string]Sandbox sandboxes map[string]Sandbox
idIndex *truncindex.TruncIndex idIndex *truncindex.TruncIndex
labels *label.Store
} }
// NewStore creates a sandbox store. // NewStore creates a sandbox store.
func NewStore() *Store { func NewStore(labels *label.Store) *Store {
return &Store{ return &Store{
sandboxes: make(map[string]Sandbox), sandboxes: make(map[string]Sandbox),
idIndex: truncindex.NewTruncIndex([]string{}), idIndex: truncindex.NewTruncIndex([]string{}),
labels: labels,
} }
} }
...@@ -79,6 +82,9 @@ func (s *Store) Add(sb Sandbox) error { ...@@ -79,6 +82,9 @@ func (s *Store) Add(sb Sandbox) error {
if _, ok := s.sandboxes[sb.ID]; ok { if _, ok := s.sandboxes[sb.ID]; ok {
return store.ErrAlreadyExist return store.ErrAlreadyExist
} }
if err := s.labels.Reserve(sb.ProcessLabel); err != nil {
return err
}
if err := s.idIndex.Add(sb.ID); err != nil { if err := s.idIndex.Add(sb.ID); err != nil {
return err return err
} }
...@@ -125,6 +131,7 @@ func (s *Store) Delete(id string) { ...@@ -125,6 +131,7 @@ func (s *Store) Delete(id string) {
// So we need to return if there are error. // So we need to return if there are error.
return return
} }
s.labels.Release(s.sandboxes[id].ProcessLabel)
s.idIndex.Delete(id) // nolint: errcheck s.idIndex.Delete(id) // nolint: errcheck
delete(s.sandboxes, id) delete(s.sandboxes, id)
} }
...@@ -151,7 +151,7 @@ github.com/container-storage-interface/spec/lib/go/csi ...@@ -151,7 +151,7 @@ github.com/container-storage-interface/spec/lib/go/csi
github.com/containerd/cgroups github.com/containerd/cgroups
# github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 # github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50
github.com/containerd/console github.com/containerd/console
# github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69 => github.com/rancher/containerd v1.3.3-k3s1 # github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69 => github.com/rancher/containerd v1.3.3-k3s2
github.com/containerd/containerd github.com/containerd/containerd
github.com/containerd/containerd/api/events github.com/containerd/containerd/api/events
github.com/containerd/containerd/api/services/containers/v1 github.com/containerd/containerd/api/services/containers/v1
...@@ -288,7 +288,7 @@ github.com/containerd/continuity/pathdriver ...@@ -288,7 +288,7 @@ github.com/containerd/continuity/pathdriver
github.com/containerd/continuity/proto github.com/containerd/continuity/proto
github.com/containerd/continuity/syscallx github.com/containerd/continuity/syscallx
github.com/containerd/continuity/sysx github.com/containerd/continuity/sysx
# github.com/containerd/cri v0.0.0-00010101000000-000000000000 => github.com/rancher/cri v1.3.0-k3s.3 # github.com/containerd/cri v0.0.0-00010101000000-000000000000 => github.com/rancher/cri v1.3.0-k3s.4
github.com/containerd/cri github.com/containerd/cri
github.com/containerd/cri/pkg/annotations github.com/containerd/cri/pkg/annotations
github.com/containerd/cri/pkg/api/runtimeoptions/v1 github.com/containerd/cri/pkg/api/runtimeoptions/v1
...@@ -306,6 +306,7 @@ github.com/containerd/cri/pkg/server/io ...@@ -306,6 +306,7 @@ github.com/containerd/cri/pkg/server/io
github.com/containerd/cri/pkg/store github.com/containerd/cri/pkg/store
github.com/containerd/cri/pkg/store/container github.com/containerd/cri/pkg/store/container
github.com/containerd/cri/pkg/store/image github.com/containerd/cri/pkg/store/image
github.com/containerd/cri/pkg/store/label
github.com/containerd/cri/pkg/store/sandbox github.com/containerd/cri/pkg/store/sandbox
github.com/containerd/cri/pkg/store/snapshot github.com/containerd/cri/pkg/store/snapshot
github.com/containerd/cri/pkg/util github.com/containerd/cri/pkg/util
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment