Compare commits

...

150 Commits

Author SHA1 Message Date
Antonio Murdaca 54e76afc03
Merge pull request #1281 from wking/gofmt-show-diff
Makefile: Use 'git diff' to show gofmt changes
2018-01-24 15:32:49 +01:00
Daniel J Walsh 4fee97abe3
Merge pull request #1278 from remore/patch-1
Fix a few minor errors in the tutorial document
2018-01-24 04:15:33 -05:00
Kei Sawada a50f352eb4 Update tutorial.md to fix a few minor errors
Signed-off-by: Kei Sawada <k@swd.cc>
2018-01-24 14:47:32 +09:00
Mrunal Patel ed40d645cd
Merge pull request #1255 from runcom/panics-grpc-getters
server: use grpc getters to avoid panics
2018-01-23 07:43:08 -08:00
W. Trevor King 8dbc2d1fff Makefile: Use 'git diff' to show gofmt changes
This makes fixing errors easier.  Before this commit, errors looked
like [1]:

  $ make gofmt
  !!! 'gofmt -s' needs to be run on the following files:
  ./lib/config.go
  make: *** [gofmt] Error 1

But that's not very helpful when your local gofmt thinks the file is
fine.  With this commit, errors will look like:

  $ make gofmt
  find . -name '*.go' ! -path './vendor/*' -exec gofmt -s -w {} \+
  git diff --exit-code
  diff --git a/lib/config.go b/lib/config.go
  index 1acca8c7..6a63b2b0 100644
  --- a/lib/config.go
  +++ b/lib/config.go
  @@ -2,7 +2,7 @@ package lib

   import (
          "bytes"
  -"io/ioutil"
  +       "io/ioutil"

          "github.com/BurntSushi/toml"
          "github.com/kubernetes-incubator/cri-o/oci"
  make: *** [Makefile:68: gofmt] Error 1

(or whatever, I just stuffed in a formatting error for demonstration
purposes).

Also remove the helper script in favor of direct Makefile calls,
because with Git handling difference reporting and exit status, this
becomes a simpler check.  find's -exec, !, and -path arguments are
specified in POSIX [2].

[1]: https://travis-ci.org/kubernetes-incubator/cri-o/jobs/331949394#L1075
[2]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html

Signed-off-by: W. Trevor King <wking@tremily.us>
2018-01-22 16:47:09 -08:00
Mrunal Patel ddb14b7303
Merge pull request #1269 from wking/server-capabilities-setup-helper
server/container_create: Factor out setupCapabilities helper
2018-01-22 15:29:22 -08:00
Mrunal Patel 924821e4bf
Merge pull request #1277 from wking/namespace-test-helper
test/namespaces: Factor out pid_namespace_test helper
2018-01-20 19:49:38 -08:00
W. Trevor King 080b84dfcd test/namespaces: Factor out pid_namespace_test helper
DRY up this code.  The ${parameter:-word} syntax is in POSIX [1].

[1]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02

Signed-off-by: W. Trevor King <wking@tremily.us>
2018-01-20 15:58:47 -08:00
Mrunal Patel 214096b7ed
Merge pull request #1268 from wking/libdevmapper-install-check
hack/libdm_installed.sh: Add a test for libdevmapper.h
2018-01-20 09:19:24 -08:00
Antonio Murdaca 8c87b6104f
Merge pull request #1267 from mrunalp/update_readme_1.9
Add 1.9 release to compatibility table
2018-01-20 02:28:20 +01:00
Mrunal Patel b7995aa526
Merge pull request #1275 from wking/remove-unused-play-png
docs: Remove the unused play.png
2018-01-19 17:02:33 -08:00
W. Trevor King 822a6516cf docs: Remove the unused play.png
The last consumer was removed in 1bf6d203 (Remove kpod code after
repository move, 2017-11-02, #1111).

Signed-off-by: W. Trevor King <wking@tremily.us>
2018-01-19 16:12:39 -08:00
W. Trevor King 523326b7ba server/container_create: Factor out setupCapabilities helper
Having a separate function holding the details of this makes reading
createSandboxContainer easier.

While I was moving the code, I've also cleaned up two things:

* The nil capabilities check is now earlier, where before it had been
  between the ALL handling and the non-ALL handling.

* I've added a capPrefixed variable to avoid having multiple
  toCAPPrefixed calls per capability.

Signed-off-by: W. Trevor King <wking@tremily.us>
2018-01-19 11:52:45 -08:00
W. Trevor King 826298483a hack/libdm_installed: Add a test for libdevmapper.h
Avoid crashing 'make' with:

  No package 'devmapper' found

by disabling the devmapper driver when the library it requires is not
installed.  Also give the libdm_no_deferred_remove script a more
specific name to avoid confusion.

Signed-off-by: W. Trevor King <wking@tremily.us>
2018-01-19 11:43:24 -08:00
Mrunal Patel 7851115693 Add 1.9 release to compatibility table
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
2018-01-19 10:37:51 -08:00
Antonio Murdaca 77561e95cf
Merge pull request #1264 from wking/test-readme-plugins-moved-from-cni
test/README: Update the CNI plugins instructions for /cni → /plugins
2018-01-18 23:58:08 +01:00
Antonio Murdaca cbfdda868a
Merge pull request #1263 from wking/doc-stale-make-output
kubernetes: Simplify and freshen the required-files table
2018-01-18 23:54:15 +01:00
W. Trevor King 282b900433 test/README: Update the CNI plugins instructions for /cni -> /plugins
Catching up with the Dockerfile change from f51b0a10 (Dockerfile: move
to containernetworking/plugins, 2017-05-25, #536).  The new plugins
commit from f51b0a10 is still the current Dockerfile entry.

This commit also replaces the previous 'go get' call with a git clone
to match the Dockerfile's approach.  I've added an additional 'cd'
call so I don't have to repeat $GOPATH/... more than once, but other
than that, the example matches the current Dockerfile entry.

I've also removed some line-continuation slashes we've been dragging
around since the section landed 07ccda33 (tests: Install CNI
configuration files by default, 2017-04-06, #434).  I'm guessing they
were a copy/paste bug from the Dockerfile, but this example has new
prompts for each command (so it doesn't need continuation) while the
Dockerfile is using && chaining (so it does).

Signed-off-by: W. Trevor King <wking@tremily.us>
2018-01-18 14:12:33 -08:00
Mrunal Patel 1bb5846d7d
Merge pull request #1261 from wking/clear-containers-moved
test/README: Clear Containers moved to clearcontainers/runtime
2018-01-18 14:01:42 -08:00
W. Trevor King 15d839ea0d kubernetes: Simplify and freshen the required-files table
The cri-o entries are stale vs. the content currently installed by the
Makefile.  This commit drops them and just references the make call
before starting the table, which lets us stay DRY.

runc is not built from the cri-o repository.  The docs have claimed it
was since 983aec63 (doc: Add instruction to run cri-o with kubernetes,
2017-01-31, #353), but it's independent like the CNI plugins.

The CNI plugins were moved to containernetworking/plugins in
containernetworking/cni@bc0d09e (plugins: moved to
containernetworking/plugins, 2017-05-17, containernetworking/cni#457).

I've added a link to the in-repo policy.json example.  We probably
also want to link to the docs (for the version we vendor?) [1], but
I've left that alone for now.

The CNI config examples were removed from the project README in
9088a12c (contrib: cni: provide example CNI configurations,
2016-12-24, #295).  I've adjusted the reference to point to the new
location, although again, I'd rather replace this with links to
upstream docs.

[1]: 3d0304a021/docs/policy.json.md

Signed-off-by: W. Trevor King <wking@tremily.us>
2018-01-18 13:49:50 -08:00
W. Trevor King bf8a99c085 tutorial: Drop 'make install' output to stay DRY
'make install' hasn't installed crio.conf since 8b632729 (Install to
/usr/local to avoid conflicts with vendor binaries, 2017-01-04, #304).
And Make output is usually not particularly interesting.

Signed-off-by: W. Trevor King <wking@tremily.us>
2018-01-18 13:27:39 -08:00
W. Trevor King 2bf750c871 tutorial: Drop install.config output to stay DRY
install.config has also installed rio-umount.conf since 51b225474
(Tell oci-umount where to remove mountpoints inside container, #937,
2017-09-21).  And Make output is usually not particularly interesting.

Signed-off-by: W. Trevor King <wking@tremily.us>
2018-01-18 13:18:28 -08:00
Mrunal Patel ba2b4a03d0
Merge pull request #1262 from wking/mailmap
.mailmap: Add entries for inconsistent users
2018-01-18 10:55:53 -08:00
W. Trevor King 8c7c70c2db .mailmap: Add entries for inconsistent users
Where the same user had multiple entries, I mostly went with whichever
entry had the most-recent non-merge commits.

The order is alphabetical according to Emacs' sort-lines.

Signed-off-by: W. Trevor King <wking@tremily.us>
2018-01-18 10:17:00 -08:00
W. Trevor King e124834b0d test/README: Clear Containers moved to clearcontainers/runtime
And changed the name of their binary.  This commit catches the docs up
with intel/cc-oci-runtime#1065 (merged 2017-09-25).

Signed-off-by: W. Trevor King <wking@tremily.us>
2018-01-18 09:47:56 -08:00
Antonio Murdaca cb8033cd19
Merge pull request #1244 from rhatdan/hooks-args
Allow additional arguments to be passed into hooks
2018-01-15 23:29:45 +01:00
Antonio Murdaca 8c190a683c
server: use grpc getters to avoid panics
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2018-01-12 16:14:29 +01:00
Mrunal Patel d0e0303921
Merge pull request #1252 from runcom/node-e2e
[DO NOT MERGE] contrib: test: add node-e2e job
2018-01-11 10:13:36 -08:00
Antonio Murdaca 8d2a572ead
contrib: test: add node-e2e job
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2018-01-11 16:56:47 +01:00
Daniel J Walsh 22e25158ca
Merge pull request #1251 from vbatts/Makefile_config_target
Makefile: installing a config, requires a config
2018-01-11 06:12:47 -05:00
Vincent Batts 27c2eda635
Makefile: installing a config, requires a config
Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
2018-01-10 16:23:35 -05:00
Daniel J Walsh 23d20c9db5 Allow additional arguments to be passed into hooks
If a packager wants to be able to support addititional arguments on his
hook this will allow them to setup the configuration with these arguments.

For example this would allow a hook developer to add support for a --debug
flag to change the level of debugging in his hook.

In order to complete this task, I had to vendor in the latest
github.com://opencontainers/runtime-tools, which caused me to have to fix a
Mount and Capability interface calls

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2018-01-09 13:44:16 -05:00
Mrunal Patel 41aaf4e3d8
Merge pull request #1250 from giuseppe/fix-tmpdir-files
syscontainer: create /var/run/crio
2018-01-09 10:01:11 -08:00
Giuseppe Scrivano 2cb22eba49
syscontainer, fedora: create /var/run/crio
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2018-01-09 18:01:03 +01:00
Giuseppe Scrivano 6bb1b7e17d
syscontainer, rhel: create /var/run/crio
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2018-01-09 18:00:53 +01:00
Giuseppe Scrivano b1b380d67b
syscontainer, centos: create /var/run/crio
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2018-01-09 18:00:43 +01:00
Antonio Murdaca 6f4d7c1ae0
Merge pull request #1216 from rhatdan/conmon
Improve error messages on missing runtime
2018-01-06 14:48:22 +01:00
Mrunal Patel c351bc81e1
Merge pull request #1245 from giuseppe/system-container-read-env-from-file
contrib: system containers read env from /etc/sysconfig/crio-(network|storage)
2018-01-04 14:31:43 -08:00
Giuseppe Scrivano b5167d4e8f
syscontainer, centos: read env variables from files
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2018-01-04 20:14:52 +01:00
Giuseppe Scrivano 1f75ec82e1
syscontainer, fedora: read env variables from files
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2018-01-04 20:14:39 +01:00
Giuseppe Scrivano 3881f375b9
syscontainer, rhel: read env variables from files
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2018-01-04 20:14:29 +01:00
Mrunal Patel ad46c581fa
Merge pull request #1243 from rhatdan/Makefile
Add -i flag to speed up compilation of cri-o packages
2018-01-04 10:54:48 -08:00
Daniel J Walsh 3c1c6d047e Add -i flag to speed up compilation of cri-o packages
Instead of compiling all of the *.go files each time, the
-i flag will cause them to be only compiled if they changed.

This will make developers much happier.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2018-01-04 10:53:33 -05:00
Mrunal Patel a34038350c
Merge pull request #1237 from spiffxp/update-code-of-conduct
Update code-of-conduct.md
2018-01-02 09:38:52 -08:00
Aaron Crickenberger a28eb8374e Update code-of-conduct.md
Refer to kubernetes/community as authoritative source for code of conduct

Signed-off-by: Aaron Crickenberger <spiffxp@gmail.com>
2018-01-02 06:55:21 -08:00
Mrunal Patel 295a11eb17
Merge pull request #1239 from jongwu/enable_arm64
Add bsdmainutils tool to Dockerfile to enable integration test on arm64
2018-01-01 18:04:27 -08:00
Mrunal Patel 28976738de
Merge pull request #1240 from wanghaoran1988/fix_log
fix log
2018-01-01 18:03:30 -08:00
Haoran Wang 88b13dfddf fix log
Signed-off-by: Haoran Wang <haowang@redhat.com>
2017-12-29 14:25:55 +08:00
Jianyong Wu 8b1fefad71 Add bsdmainutils tool to Dockerfile to enable integration test on arm64
Build image for integration test on arm64 will fail for lack of
hexdump. Add bsdmainutils tool to eliminate that failure and let
build image succussfully

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
2017-12-28 16:45:56 +08:00
Mrunal Patel 6b91df3da7
Merge pull request #1236 from runcom/cpuset-ctr-create
container_create: set cpuset cpus|mems
2017-12-23 12:20:45 -08:00
Antonio Murdaca de0be63495
container_create: set cpuset cpus|mems
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-12-20 19:20:57 +01:00
Daniel J Walsh a85f3127d8 Improve error messages on missing runtime
Also stat.h is included twice,
Add more info on log file name and error when failing to open.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2017-12-18 16:46:19 -05:00
Daniel J Walsh 6c0b79b706
Merge pull request #1208 from runcom/moar-tests
contrib: test: integration: enable more e2e kube tests
2017-12-18 10:25:50 -05:00
Mrunal Patel aee7dea272
Merge pull request #1227 from runcom/bump-runc-systemd-race
bump runc to c6e4a1ebeb1a72b529c6f1b6ee2b1ae5b868b14f
2017-12-15 08:56:40 -08:00
Antonio Murdaca e344ad105a
Merge pull request #1116 from nalind/storage-update-2
Update containers/image and containers/storage
2017-12-15 17:01:29 +01:00
Antonio Murdaca 43119a7b13
Merge branch 'lock-free-ops' into moar-tests
* lock-free-ops:
  lib,oci: drop stateLock when possible
2017-12-15 16:46:42 +01:00
Antonio Murdaca ecc572e7cf
lib,oci: drop stateLock when possible
Should fix a possible deadlock in, at least, ListPodSandbox.
There seems to be no reason to hold stateLock when doing operations on
the memory_store for containers and sandboxes.

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-12-15 15:31:58 +01:00
Antonio Murdaca 455245e65b
bump runc to c6e4a1ebeb1a72b529c6f1b6ee2b1ae5b868b14f
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-12-15 14:33:44 +01:00
Antonio Murdaca 7d2bde110a
contrib: test: integration: enable more e2e kube tests
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-12-14 22:21:42 +01:00
Nalin Dahyabhai fa90249c59 Playbooks: install the atomic-registries package
Install atomic-registries to get a /etc/containers/registries.conf file,
so that we can resolve image names that don't include domain portions.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 14:23:53 -05:00
Nalin Dahyabhai 72442d0957 Don't skip a critest that we now pass
We can pass the "listImage should get exactly 2 repoTags in the result
image" test now, so we no longer need to skip it.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 14:23:53 -05:00
Nalin Dahyabhai 0ab8c507f4 Install python-rhsm-certificates, handle python-boto
Add python-rhsm-certificates to the list of packages that we require, so
that the required certificates are available for the
pull-image-with-signature tests.

Add per-distribution package install tasks so that we install either
python2-boto or python-boto, depending on whether we're running on
Fedora or RHEL/CentOS, respectively.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 14:23:53 -05:00
Nalin Dahyabhai 492f758176 Playbooks: don't assume the default network is eth0
Replace instances of "ansible_eth0.ipv4.address" with
"ansible_default_ipv4.address" in the integration test playbook, so that
we can run tests without depending on the name of the primary network
interface being "eth0".

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 14:23:53 -05:00
Nalin Dahyabhai 893aa4e8c7 Be more diligent about cleaning up failed-to-create containers
If server/Server.createSandboxContainer() fails after calling
server/Server.StorageRuntimeServer().CreateContainer(), cleanup logic in
server/Server.CreateContainer() won't try to clean it up, but we still
need to clean up the on-disk container and its layer.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 14:23:53 -05:00
Nalin Dahyabhai 6a456d1502 Use crictl instead of crioctl in image integration tests
Use crictl instead of crioctl in some of the integration tests that
exercise image handling.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 14:23:53 -05:00
Nalin Dahyabhai 5ea050fc12 Handle truncated IDs in imageService.ResolveNames()
Have ResolveNames() check if the value that it's been given is a
truncated version of the ID of a locally-available image, and if it is,
return the value as it was given.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 14:23:53 -05:00
Nalin Dahyabhai ff7bbb4f0d Switch to ImageServer.UntagImage in RemoveImage handler
Add an UntagImage() method to pkg/storage/ImageServer, which will check
if the passed-in NameOrID is a name.  If so, it merely removes that name
from the image, removing the image only if it was the last name that the
image had.  If the NameOrID is an image ID, the image is removed, as
RemoveImage() does.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 14:23:53 -05:00
Nalin Dahyabhai f3b7065bd8 Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.

In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.

In Server.ListImages(), be sure to only return tagged names in the
RepoTags field.  In Server.ImageStatus(), also return canonical
references in the RepoDigests field.

In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 14:23:52 -05:00
Nalin Dahyabhai 553979e1fc storage: API fixups
github.com/containers/image/types.ImageReference.NewImage() can take a
*github.com/containers/image/types.SystemContext now, so pass it one if
pkg/storage/imageService.CanPull() has one to give it.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 11:06:55 -05:00
Nalin Dahyabhai 0651d3a8de Update containers/image and containers/storage
Bump containers/image to 3d0304a02154dddc8f97cc833aa0861cea5e9ade, and
containers/storage to 0d32dfce498e06c132c60dac945081bf44c22464.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-12-14 11:06:23 -05:00
Mrunal Patel 2fa1f3f74a
Merge pull request #1221 from runcom/split-critest-from-e2e
CI: split critest from e2e
2017-12-13 16:53:20 -08:00
Antonio Murdaca d91df68638
CI: split critest from e2e
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-12-14 00:09:36 +01:00
Mrunal Patel da50e6ca11
Merge pull request #1197 from runcom/sys-cont
contrib: import system containers
2017-12-13 09:22:55 -08:00
Mrunal Patel ebc249cad8
Merge pull request #1214 from runcom/fix-1.10-vendor
vendor: bump to kube 1.10/master
2017-12-11 11:14:15 -08:00
Antonio Murdaca f317ffce5b
vendor: bump to kube 1.10/master
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-12-11 16:45:48 +01:00
Mrunal Patel a85ea609db
Merge pull request #1207 from runcom/fix-exec-termianl
container_exec: fix terminal true process json
2017-12-07 14:44:38 -08:00
Antonio Murdaca afeab27a36
container_exec: fix terminal true process json
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-12-07 20:51:05 +01:00
Mrunal Patel 1f3fbdc987
Merge pull request #1206 from nlacasse/state-ignore-stderr
Only parse stdout from "state" command.  Ignore stderr.
2017-12-07 11:29:25 -08:00
Nicolas Lacasse 1138af9e59 Don't parse stderr as json when calling "state" command.
Some oci runtimes may used stderr for logging.  Cri-o should not try to
parse this output as json when calling the "state" command.

Signed-off-by: Nicolas Lacasse <nlacasse@google.com>
2017-12-06 09:52:54 -08:00
Antonio Murdaca 06904d4dbb
contrib: import system containers
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-12-02 12:24:40 +01:00
Mrunal Patel 85f303f3ff
Merge pull request #1198 from runcom/list-sandboxes-refactor
lib: sandbox: refactor to memory store
2017-12-01 11:36:46 -08:00
Mrunal Patel 989d275e76
Merge pull request #1170 from alexandrst88/fix-tutorial
Update install.md relevant documentation
2017-12-01 09:20:38 -10:00
Antonio Murdaca d168fc5fec
lib: sandbox: refactor to memory store
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-12-01 18:16:08 +01:00
Daniel J Walsh b9ffd277b9
Merge pull request #1192 from runcom/no-libkpod
libkpod -> lib rename
2017-12-01 08:44:44 -05:00
Antonio Murdaca 910cfab6e9
Merge pull request #910 from sameo/topic/bats
test: Add timeout before checking for status
2017-12-01 13:30:13 +01:00
Samuel Ortiz a2e08d5dc4 test: Add timeout before checking for status
Under some slow environment (nested VMs) or with some
not as fast runtimes (Clear Containers), asking for a
status right away is racy.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2017-12-01 10:21:50 +01:00
Antonio Murdaca 0eaa52c356
Merge pull request #1184 from willstudy/unit_test
Adding unit tests for server/secrets.go
2017-12-01 10:04:30 +01:00
Antonio Murdaca 0ab5e80c38
Merge pull request #1193 from mrunalp/go_1.8.5
Bump up go version to 1.8.5
2017-11-30 22:19:34 +01:00
Mrunal Patel 2cae11ba35 Merge pull request #1189 from runcom/fix-apparmor-master
container_create: fix apparmor from container config
2017-11-30 08:56:46 -10:00
Mrunal Patel 40da5c2c16
Merge pull request #1186 from runcom/fixups-env-master
Fix env handling on exec
2017-11-30 08:54:33 -10:00
Antonio Murdaca b8bba70f99
libkpod -> lib rename
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-30 17:08:26 +01:00
Mrunal Patel 32d2c2d57c Bump up go version to 1.8.5
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
2017-11-30 08:02:02 -08:00
Antonio Murdaca c8aad704dd
container_create: fix apparmor from container config
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-30 16:12:16 +01:00
Antonio Murdaca ea0bf448fe
test: add exec/execsync env conflict test
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-30 12:54:58 +01:00
Antonio Murdaca 902acca4af
container_create: correctly set image and kube envs
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-30 12:28:50 +01:00
Antonio Murdaca b59f31a2d5
oci: do not append conmon env to container process
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-30 11:23:42 +01:00
Antonio Murdaca c6f68f1bf1
container_exec: use process file with runc exec
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-30 11:23:37 +01:00
Oleksandr Stepanov a71948e9e7
Fixed install.md documentation
Signed-off-by: Oleksandr Stepanov <alexandrst88@gmail.com>
2017-11-30 10:38:20 +02:00
Mrunal Patel 6faef13293
Merge pull request #1168 from weiwei04/remove_crioctl
remove crioctl source code
2017-11-29 17:06:51 -10:00
Mrunal Patel b2a78eba2b
Merge pull request #1185 from runcom/fix-runtime-deps
README.md: add all runtime dependencies
2017-11-29 05:47:13 -10:00
Antonio Murdaca bae4d2241f
README.md: add all runtime dependencies
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-29 15:57:17 +01:00
Wei Wei 3006a2159a drop crioctl source code
Signed-off-by: Wei Wei <weiwei.inf@gmail.com>
2017-11-29 21:07:50 +08:00
Antonio Murdaca 5f5a7a3648
Merge pull request #1162 from mrunalp/add_partial_support
conmon: Add support for partial/newline log tags
2017-11-29 11:47:09 +01:00
Liu Chang c0ad5277e6 Adding unit tests for server/secrets.go
Signed-off-by: Liu Chang <liuchang@qiniu.com>
2017-11-29 17:42:19 +08:00
Mrunal Patel d10490bccf test: Add an integration test for partial line in logs
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
2017-11-28 18:57:26 -08:00
Mrunal Patel 4cf4137be0 conmon: Add support for partial/newline log tags
This is for ttps://github.com/kubernetes/kubernetes/pull/55922

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
2017-11-28 18:57:21 -08:00
Mrunal Patel 4a32d0ff33
Merge pull request #1183 from runcom/fix-image-pull-master
image_pull: fix image resolver
2017-11-28 16:49:15 -10:00
Antonio Murdaca 87f1ae214f
image_pull: fix image resolver
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-28 23:53:18 +01:00
Mrunal Patel 63371009ae
Merge pull request #1181 from runcom/remove-git-validation-ci
CI: drop git-validation as it's never used
2017-11-28 12:46:35 -10:00
Antonio Murdaca 03fb727f2b
CI: drop git-validation as it's never used
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-28 11:40:06 +01:00
Antonio Murdaca 851759c73b
Merge pull request #1179 from willstudy/unit_test
Adding unit tests for server/utils.go
2017-11-27 19:34:24 +01:00
Daniel J Walsh 8518e06e81
Merge pull request #1166 from willstudy/dev
Improve the readability of crio.8.md
2017-11-27 11:08:05 -05:00
Liu Chang 42800cc96b Adding unit tests for server/utils.go
Signed-off-by: Liu Chang <liuchang@qiniu.com>
2017-11-27 16:01:00 +08:00
Liu Chang bf515de94d Improve the readability of crio.8.md
Signed-off-by: Liu Chang <liuchang@qiniu.com>
2017-11-27 11:04:09 +08:00
Mrunal Patel 070b8bfdc5
Merge pull request #1176 from runcom/fix-e2e-1.0
contrib: parametrize the crio socket for kube
2017-11-22 09:36:15 -10:00
Mrunal Patel 7508cdeace
Merge pull request #1173 from runcom/fix-cve
Add /proc/scsi to masked paths
2017-11-22 05:35:33 -10:00
Antonio Murdaca 67e2d28c86
Merge pull request #1171 from WeiZhang555/fix-readme
Cleanup: remove redundant lines in tutorial
2017-11-22 14:53:44 +01:00
Antonio Murdaca 2f344c7533
contrib: parametrize the crio socket for kube
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-22 14:14:06 +01:00
Antonio Murdaca a75362dca0
Add /proc/scsi to masked paths
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-22 12:25:43 +01:00
z00280905 2fbbf49541 Cleanup: remove redundant lines in tutorial
Signed-off-by: z00280905 <zhangwei555@huawei.com>
2017-11-22 17:37:11 +08:00
Mrunal Patel 73c1a9823f
Merge pull request #1167 from runcom/wire-critest
CI: wire in critest
2017-11-21 06:16:19 -10:00
Antonio Murdaca 6da7193ff5
CI: wire in critest
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-21 11:19:37 +01:00
Antonio Murdaca b3f59f31ad
Merge pull request #1159 from weiwei04/replace_crioctl_with_crictl_wip
Replace crioctl with crictl
2017-11-20 15:27:30 +01:00
Wei Wei 25dfde9044 replace crioctl with crictl
Signed-off-by: Wei Wei <weiwei.inf@gmail.com>
2017-11-20 13:46:52 +08:00
Daniel J Walsh 6c8ab88e9e
Merge pull request #1163 from mrunalp/pid_ns_opt_in
Make pid namespace sharing optional and disabled by default
2017-11-19 06:06:35 -05:00
Mrunal Patel 946307e5c2 Make pid namespace sharing optional and disabled by default
We reverse the logic so that pid ns sharing is disabled by default.

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
2017-11-18 06:47:06 -08:00
Daniel J Walsh e23723d62e
Merge pull request #1161 from cevich/nuke_old_rpm_stuffs
Remove disused contrib/rpm
2017-11-17 15:07:00 -05:00
Mrunal Patel d68da8929a
Merge pull request #1149 from weiwei04/share_pid_namespace
share pid namespace for Pod container
2017-11-17 08:12:49 -10:00
Chris Evich bbd9a6528c Remove disused contrib/rpm
I don't believe the files in this dir are actually used anymore.  Remove
them so content can be added to this directory in the future w/o
clashing.

Signed-off-by: Chris Evich <cevich@redhat.com>
2017-11-17 11:49:18 -05:00
Wei Wei 702ab3ee3a share pid namespace for Pod container
Signed-off-by: Wei Wei <weiwei.inf@gmail.com>
2017-11-17 09:56:33 +08:00
Mrunal Patel 7b837b5a1e
Merge pull request #1156 from weiwei04/replace_crioctl_with_crictl
replace crioctl with crictl in e2e
2017-11-15 09:38:21 -10:00
Daniel J Walsh 31111ba651
Merge pull request #1154 from runcom/move-crio-socket
Move crio default sock to /var/run/crio/crio.sock
2017-11-15 10:14:22 -05:00
Wei Wei b0b6611bdf replace crioctl in e2e with crictl
Signed-off-by: Wei Wei <weiwei.inf@gmail.com>
2017-11-15 16:15:54 +08:00
Antonio Murdaca 429a687ced
Merge pull request #1153 from mrunalp/add_kube_version_var
test: Add a version var for kube branches
2017-11-14 23:06:01 +01:00
Mrunal Patel 3596aa0155 test: Add a version var for kube branches
This allows us to cache a k8s branch for cri-o 1.0 branch
while allowing overriding of k8s branch in master and other
newer cri-o branches.

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
2017-11-14 09:58:53 -08:00
Mrunal Patel 8fe6dd36a4
Move crio default sock to /var/run/crio/crio.sock
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-14 16:11:43 +01:00
Daniel J Walsh e7471600f8
Merge pull request #585 from runcom/comp-matrix
README.md: add compatibility matrix
2017-11-14 10:02:40 -05:00
Antonio Murdaca 21252ed22d
Merge pull request #1151 from mdshuai/fix-test-typo
fix syntax for test/README.md
2017-11-14 10:36:47 +01:00
Antonio Murdaca 692af73b0b
README.md: add compatibility matrix
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-14 09:39:30 +01:00
DeShuai Ma e90e0c7062 fix typo for test/README.md
Signed-off-by: DeShuai Ma <dma@redhat.com>
2017-11-14 15:29:27 +08:00
Mrunal Patel a447b2985c
Merge pull request #1148 from agonzalezro/config-tests
Add tests for server/config.go
2017-11-13 18:58:50 -10:00
Mrunal Patel 6ed8fbeea2
Merge pull request #1150 from runcom/bump-kube-1.9-master
vendor: bump to Kube 1.9/master
2017-11-13 10:54:45 -10:00
Antonio Murdaca 7a675ccd92
vendor: bump to Kube 1.9/master
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-13 19:57:20 +01:00
Mrunal Patel 7076c73172
Merge pull request #1152 from runcom/deprecate-crioctl
hack: validate tests for crioctl deprecation
2017-11-13 07:41:57 -10:00
Antonio Murdaca 8ae0aee7e5
hack: validate tests for crioctl deprecation
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-13 16:55:45 +01:00
Álex González c3f86cd016
Add tests for server/config.go
The tests are trying to read an write configuration files and check that the
fields are being set or saved properly.

A folder fixtures/ was created on server/ as well adding an example crio.conf
file to it.

Note: some extra paths about Vagrant and VSCode were added to gitignore.
Signed-off-by: Álex González <agonzalezro@gmail.com>
2017-11-13 13:43:47 +01:00
Mrunal Patel 25ac83196f
Merge pull request #1146 from runcom/setspp
container_create: set the seccomp profile in the container object
2017-11-12 09:36:35 -10:00
Antonio Murdaca 586eda8245
container_create: set the seccomp profile in the container object
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-12 17:51:32 +01:00
Daniel J Walsh edf2300205
Merge pull request #1142 from runcom/fixies-bump
Bump v1.8.0
2017-11-12 06:24:35 -05:00
Antonio Murdaca 4d1e77ff9d
version: bump v1.9.0-dev
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
2017-11-12 01:54:20 +01:00
918 changed files with 79174 additions and 28456 deletions

5
.gitignore vendored
View File

@ -11,3 +11,8 @@
/test/bin2img/bin2img
/test/checkseccomp/checkseccomp
/test/copyimg/copyimg
Vagrantfile
.vagrant/
.vscode/

10
.mailmap Normal file
View File

@ -0,0 +1,10 @@
Aleksa Sarai <asarai@suse.de> <asarai@suse.com>
Antonio Murdaca <runcom@redhat.com> <runcom@users.noreply.github.com>
CuiHaozhi <cuihaozhi@chinacloud.com.cn> <cuihz@wise2c.com>
Daniel J Walsh <dwalsh@redhat.com>
Haiyan Meng <hmeng@redhat.com> <haiyanalady@gmail.com>
Lorenzo Fontana <lo@linux.com> <fontanalorenz@gmail.com>
Mrunal Patel <mrunalp@gmail.com> <mpatel@redhat.com>
Mrunal Patel <mrunalp@gmail.com> <mrunal@me.com>
Pengfei Ni <feiskyer@gmail.com> <feiskyer@users.noreply.github.com>
Tobias Klauser <tklauser@distanz.ch> <tobias.klauser@gmail.com>

View File

@ -38,6 +38,7 @@ RUN apt-get update && apt-get install -y \
netcat \
socat \
--no-install-recommends \
bsdmainutils \
&& apt-get clean
# install bats
@ -56,7 +57,7 @@ RUN mkdir -p /usr/src/criu \
&& rm -rf /usr/src/criu
# Install runc
ENV RUNC_COMMIT 84a082bfef6f932de921437815355186db37aeb1
ENV RUNC_COMMIT c6e4a1ebeb1a72b529c6f1b6ee2b1ae5b868b14f
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \

View File

@ -11,7 +11,7 @@ LIBEXECDIR ?= ${PREFIX}/libexec
MANDIR ?= ${PREFIX}/share/man
ETCDIR ?= ${DESTDIR}/etc
ETCDIR_CRIO ?= ${ETCDIR}/crio
BUILDTAGS ?= seccomp $(shell hack/btrfs_tag.sh) $(shell hack/libdm_tag.sh) $(shell hack/btrfs_installed_tag.sh) $(shell hack/ostree_tag.sh) $(shell hack/selinux_tag.sh)
BUILDTAGS ?= seccomp $(shell hack/btrfs_tag.sh) $(shell hack/libdm_installed.sh) $(shell hack/libdm_no_deferred_remove_tag.sh) $(shell hack/btrfs_installed_tag.sh) $(shell hack/ostree_tag.sh) $(shell hack/selinux_tag.sh)
CRICTL_CONFIG_DIR=${DESTDIR}/etc
BASHINSTALLDIR=${PREFIX}/share/bash-completion/completions
@ -46,7 +46,7 @@ help:
@echo "Usage: make <target>"
@echo
@echo " * 'install' - Install binaries to system locations"
@echo " * 'binaries' - Build crio, conmon, pause, and crioctl"
@echo " * 'binaries' - Build crio, conmon and pause"
@echo " * 'integration' - Execute integration tests"
@echo " * 'clean' - Clean artifacts"
@echo " * 'lint' - Execute the source code linter"
@ -64,7 +64,8 @@ lint: .gopathok
@./.tool/lint
gofmt:
@./hack/verify-gofmt.sh
find . -name '*.go' ! -path './vendor/*' -exec gofmt -s -w {} \+
git diff --exit-code
conmon:
$(MAKE) -C $@
@ -73,19 +74,16 @@ pause:
$(MAKE) -C $@
test/bin2img/bin2img: .gopathok $(wildcard test/bin2img/*.go)
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o $@ $(PROJECT)/test/bin2img
$(GO) build -i $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o $@ $(PROJECT)/test/bin2img
test/copyimg/copyimg: .gopathok $(wildcard test/copyimg/*.go)
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o $@ $(PROJECT)/test/copyimg
$(GO) build -i $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o $@ $(PROJECT)/test/copyimg
test/checkseccomp/checkseccomp: .gopathok $(wildcard test/checkseccomp/*.go)
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o $@ $(PROJECT)/test/checkseccomp
$(GO) build -i $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o $@ $(PROJECT)/test/checkseccomp
crio: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/crio $(PROJECT))
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o bin/$@ $(PROJECT)/cmd/crio
crioctl: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/crioctl $(PROJECT))
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o bin/$@ $(PROJECT)/cmd/crioctl
$(GO) build -i $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o bin/$@ $(PROJECT)/cmd/crio
crio.conf: crio
./bin/crio --config="" config --default > crio.conf
@ -99,7 +97,7 @@ endif
rm -fr test/testdata/redis-image
find . -name \*~ -delete
find . -name \#\* -delete
rm -f bin/crioctl bin/crio
rm -f bin/crio
make -C conmon clean
make -C pause clean
rm -f test/bin2img/bin2img
@ -121,7 +119,7 @@ testunit:
localintegration: clean binaries test-binaries
./test/test_runner.sh ${TESTFLAGS}
binaries: crio conmon pause crioctl
binaries: crio conmon pause
test-binaries: test/bin2img/bin2img test/copyimg/copyimg test/checkseccomp/checkseccomp
MANPAGES_MD := $(wildcard docs/*.md)
@ -139,7 +137,6 @@ install: .gopathok install.bin install.man
install.bin:
install ${SELINUXOPT} -D -m 755 bin/crio $(BINDIR)/crio
install ${SELINUXOPT} -D -m 755 bin/crioctl $(BINDIR)/crioctl
install ${SELINUXOPT} -D -m 755 bin/conmon $(LIBEXECDIR)/crio/conmon
install ${SELINUXOPT} -D -m 755 bin/pause $(LIBEXECDIR)/crio/pause
@ -149,7 +146,7 @@ install.man:
install ${SELINUXOPT} -m 644 $(filter %.5,$(MANPAGES)) -t $(MANDIR)/man5
install ${SELINUXOPT} -m 644 $(filter %.8,$(MANPAGES)) -t $(MANDIR)/man8
install.config:
install.config: crio.conf
install ${SELINUXOPT} -D -m 644 crio.conf $(ETCDIR_CRIO)/crio.conf
install ${SELINUXOPT} -D -m 644 seccomp.json $(ETCDIR_CRIO)/seccomp.json
install ${SELINUXOPT} -D -m 644 crio-umount.conf $(OCIUMOUNTINSTALLDIR)/crio-umount.conf
@ -165,7 +162,6 @@ install.systemd:
uninstall:
rm -f $(BINDIR)/crio
rm -f $(BINDIR)/crioctl
rm -f $(LIBEXECDIR)/crio/conmon
rm -f $(LIBEXECDIR)/crio/pause
for i in $(filter %.1,$(MANPAGES)); do \

View File

@ -6,6 +6,20 @@
### Status: Stable
## Compatibility matrix: CRI-O <-> Kubernetes clusters
| Version - Branch | Kubernetes branch/version | Maintenance status |
|----------------------------|-------------------------------|--------------------|
| CRI-O 1.0.x - release-1.0 | Kubernetes 1.7 branch, v1.7.x | = |
| CRI-O 1.8.x - release-1.8 | Kubernetes 1.8 branch, v1.8.x | = |
| CRI-O 1.9.x - release-1.9 | Kubernetes 1.9 branch, v1.9.x | = |
| CRI-O HEAD - master | Kubernetes master branch | ✓ |
Key:
* `✓` Changes in main Kubernetes repo about CRI are actively implemented in CRI-O
* `=` Maintenance is manual, only bugs will be patched.
## What is the scope of this project?
CRI-O is meant to provide an integration path between OCI conformant runtimes and the kubelet.
@ -64,7 +78,12 @@ For sync communication we have an IRC channel #CRI-O, on chat.freenode.net, that
## Getting started
### Prerequisites
### Runtime dependencies
- runc, Clear Containers runtime, or any other OCI compatible runtime
- socat
- iproute
- iptables
Latest version of `runc` is expected to be installed on the system. It is picked up as the default runtime by CRI-O.
@ -216,7 +235,7 @@ You can run a local version of kubernetes with CRI-O using `local-up-cluster.sh`
```shell
CGROUP_DRIVER=systemd \
CONTAINER_RUNTIME=remote \
CONTAINER_RUNTIME_ENDPOINT='/var/run/crio.sock --runtime-request-timeout=15m' \
CONTAINER_RUNTIME_ENDPOINT='/var/run/crio/crio.sock --runtime-request-timeout=15m' \
./hack/local-up-cluster.sh
```

View File

@ -28,8 +28,7 @@ storage_driver = "{{ .Storage }}"
storage_option = [
{{ range $opt := .StorageOptions }}{{ printf "\t%q,\n" $opt }}{{ end }}]
# The "crio.api" table contains settings for the kubelet/gRPC
# interface (which is also used by crioctl).
# The "crio.api" table contains settings for the kubelet/gRPC interface.
[crio.api]
# listen is the path to the AF_LOCAL socket on which crio will listen.
@ -115,6 +114,9 @@ default_mounts = [
# pids_limit is the number of processes allowed in a container
pids_limit = {{ .PidsLimit }}
# enable using a shared PID namespace for containers in a pod
enable_shared_pid_namespace = {{ .EnableSharedPIDNamespace }}
# log_size_max is the max limit for the container log size in bytes.
# Negative values indicate that no limit is imposed.
log_size_max = {{ .LogSizeMax }}

View File

@ -8,12 +8,13 @@ import (
_ "net/http/pprof"
"os"
"os/signal"
"path/filepath"
"sort"
"strings"
"time"
"github.com/containers/storage/pkg/reexec"
"github.com/kubernetes-incubator/cri-o/libkpod"
"github.com/kubernetes-incubator/cri-o/lib"
"github.com/kubernetes-incubator/cri-o/server"
"github.com/kubernetes-incubator/cri-o/version"
"github.com/opencontainers/selinux/go-selinux"
@ -31,9 +32,9 @@ var gitCommit = ""
func validateConfig(config *server.Config) error {
switch config.ImageVolumes {
case libkpod.ImageVolumesMkdir:
case libkpod.ImageVolumesIgnore:
case libkpod.ImageVolumesBind:
case lib.ImageVolumesMkdir:
case lib.ImageVolumesIgnore:
case lib.ImageVolumesBind:
default:
return fmt.Errorf("Unrecognized image volume type specified")
@ -131,6 +132,9 @@ func mergeConfig(config *server.Config, ctx *cli.Context) error {
if ctx.GlobalIsSet("pids-limit") {
config.PidsLimit = ctx.GlobalInt64("pids-limit")
}
if ctx.GlobalIsSet("enable-shared-pid-namespace") {
config.EnableSharedPIDNamespace = ctx.GlobalBool("enable-shared-pid-namespace")
}
if ctx.GlobalIsSet("log-size-max") {
config.LogSizeMax = ctx.GlobalInt64("log-size-max")
}
@ -141,7 +145,7 @@ func mergeConfig(config *server.Config, ctx *cli.Context) error {
config.PluginDir = ctx.GlobalString("cni-plugin-dir")
}
if ctx.GlobalIsSet("image-volumes") {
config.ImageVolumes = libkpod.ImageVolumesType(ctx.GlobalString("image-volumes"))
config.ImageVolumes = lib.ImageVolumesType(ctx.GlobalString("image-volumes"))
}
return nil
}
@ -293,12 +297,16 @@ func main() {
},
cli.Int64Flag{
Name: "pids-limit",
Value: libkpod.DefaultPidsLimit,
Value: lib.DefaultPidsLimit,
Usage: "maximum number of processes allowed in a container",
},
cli.BoolFlag{
Name: "enable-shared-pid-namespace",
Usage: "enable using a shared PID namespace for containers in a pod",
},
cli.Int64Flag{
Name: "log-size-max",
Value: libkpod.DefaultLogSizeMax,
Value: lib.DefaultLogSizeMax,
Usage: "maximum log size in bytes for a container",
},
cli.StringFlag{
@ -311,13 +319,13 @@ func main() {
},
cli.StringFlag{
Name: "image-volumes",
Value: string(libkpod.ImageVolumesMkdir),
Value: string(lib.ImageVolumesMkdir),
Usage: "image volume handling ('mkdir', 'bind', or 'ignore')",
},
cli.StringFlag{
Name: "hooks-dir-path",
Usage: "set the OCI hooks directory path",
Value: libkpod.DefaultHooksDirPath,
Value: lib.DefaultHooksDirPath,
Hidden: true,
},
cli.StringSliceFlag{
@ -429,6 +437,10 @@ func main() {
return fmt.Errorf("invalid --runtime value %q", err)
}
if err := os.MkdirAll(filepath.Dir(config.Listen), 0755); err != nil {
return err
}
// Remove the socket if it already exists
if _, err := os.Stat(config.Listen); err == nil {
if err := os.Remove(config.Listen); err != nil {
@ -497,7 +509,7 @@ func main() {
if graceful && strings.Contains(strings.ToLower(err.Error()), "use of closed network connection") {
err = nil
} else {
logrus.Errorf("Failed to serve grpc grpc request: %v", err)
logrus.Errorf("Failed to serve grpc request: %v", err)
}
}
}()

View File

@ -1,654 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"log"
"net/url"
"os"
"strings"
"time"
"github.com/kubernetes-incubator/cri-o/client"
"github.com/urfave/cli"
"golang.org/x/net/context"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/remotecommand"
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
)
var containerCommand = cli.Command{
Name: "container",
Aliases: []string{"ctr"},
Subcommands: []cli.Command{
createContainerCommand,
inspectContainerCommand,
startContainerCommand,
stopContainerCommand,
removeContainerCommand,
containerStatusCommand,
listContainersCommand,
execSyncCommand,
execCommand,
},
}
type createOptions struct {
// configPath is path to the config for container
configPath string
// name sets the container name
name string
// podID of the container
podID string
// labels for the container
labels map[string]string
}
var createContainerCommand = cli.Command{
Name: "create",
Usage: "create a container",
Flags: []cli.Flag{
cli.StringFlag{
Name: "pod",
Usage: "the id of the pod sandbox to which the container belongs",
},
cli.StringFlag{
Name: "config",
Value: "config.json",
Usage: "the path of a container config file",
},
cli.StringFlag{
Name: "name",
Value: "",
Usage: "the name of the container",
},
cli.StringSliceFlag{
Name: "label",
Usage: "add key=value labels to the container",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
if !context.IsSet("pod") {
return fmt.Errorf("Please specify the id of the pod sandbox to which the container belongs via the --pod option")
}
opts := createOptions{
configPath: context.String("config"),
name: context.String("name"),
podID: context.String("pod"),
labels: make(map[string]string),
}
for _, l := range context.StringSlice("label") {
pair := strings.Split(l, "=")
if len(pair) != 2 {
return fmt.Errorf("incorrectly specified label: %v", l)
}
opts.labels[pair[0]] = pair[1]
}
// Test RuntimeServiceClient.CreateContainer
err = CreateContainer(client, opts)
if err != nil {
return fmt.Errorf("Creating container failed: %v", err)
}
return nil
},
}
var startContainerCommand = cli.Command{
Name: "start",
Usage: "start a container",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "id of the container",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
err = StartContainer(client, context.String("id"))
if err != nil {
return fmt.Errorf("Starting the container failed: %v", err)
}
return nil
},
}
var stopContainerCommand = cli.Command{
Name: "stop",
Usage: "stop a container",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "id of the container",
},
cli.Int64Flag{
Name: "timeout",
Value: 10,
Usage: "seconds to wait to kill the container after a graceful stop is requested",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
err = StopContainer(client, context.String("id"), context.Int64("timeout"))
if err != nil {
return fmt.Errorf("Stopping the container failed: %v", err)
}
return nil
},
}
var removeContainerCommand = cli.Command{
Name: "remove",
Usage: "remove a container",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "id of the container",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
err = RemoveContainer(client, context.String("id"))
if err != nil {
return fmt.Errorf("Removing the container failed: %v", err)
}
return nil
},
}
var containerStatusCommand = cli.Command{
Name: "status",
Usage: "get the status of a container",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "id of the container",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
err = ContainerStatus(client, context.String("id"))
if err != nil {
return fmt.Errorf("Getting the status of the container failed: %v", err)
}
return nil
},
}
var execSyncCommand = cli.Command{
Name: "execsync",
Usage: "exec a command synchronously in a container",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "id of the container",
},
cli.Int64Flag{
Name: "timeout",
Value: 0,
Usage: "timeout for the command",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
err = ExecSync(client, context.String("id"), context.Args(), context.Int64("timeout"))
if err != nil {
return fmt.Errorf("execing command in container failed: %v", err)
}
return nil
},
}
var execCommand = cli.Command{
Name: "exec",
Usage: "prepare a streaming endpoint to execute a command in the container",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "id of the container",
},
cli.BoolFlag{
Name: "tty",
Usage: "whether to use tty",
},
cli.BoolFlag{
Name: "stdin",
Usage: "whether to stream to stdin",
},
cli.BoolFlag{
Name: "url",
Usage: "do not exec command, just prepare streaming endpoint",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
err = Exec(client, context.String("id"), context.Bool("tty"), context.Bool("stdin"), context.Bool("url"), context.Args())
if err != nil {
return fmt.Errorf("execing command in container failed: %v", err)
}
return nil
},
}
type listOptions struct {
// id of the container
id string
// podID of the container
podID string
// state of the container
state string
// quiet is for listing just container IDs
quiet bool
// labels are selectors for the container
labels map[string]string
}
var listContainersCommand = cli.Command{
Name: "list",
Usage: "list containers",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "quiet",
Usage: "list only container IDs",
},
cli.StringFlag{
Name: "id",
Value: "",
Usage: "filter by container id",
},
cli.StringFlag{
Name: "pod",
Value: "",
Usage: "filter by container pod id",
},
cli.StringFlag{
Name: "state",
Value: "",
Usage: "filter by container state",
},
cli.StringSliceFlag{
Name: "label",
Usage: "filter by key=value label",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
opts := listOptions{
id: context.String("id"),
podID: context.String("pod"),
state: context.String("state"),
quiet: context.Bool("quiet"),
labels: make(map[string]string),
}
for _, l := range context.StringSlice("label") {
pair := strings.Split(l, "=")
if len(pair) != 2 {
return fmt.Errorf("incorrectly specified label: %v", l)
}
opts.labels[pair[0]] = pair[1]
}
err = ListContainers(client, opts)
if err != nil {
return fmt.Errorf("listing containers failed: %v", err)
}
return nil
},
}
// CreateContainer sends a CreateContainerRequest to the server, and parses
// the returned CreateContainerResponse.
func CreateContainer(client pb.RuntimeServiceClient, opts createOptions) error {
config, err := loadContainerConfig(opts.configPath)
if err != nil {
return err
}
// Override the name by the one specified through CLI
if opts.name != "" {
config.Metadata.Name = opts.name
}
for k, v := range opts.labels {
config.Labels[k] = v
}
r, err := client.CreateContainer(context.Background(), &pb.CreateContainerRequest{
PodSandboxId: opts.podID,
Config: config,
// TODO(runcom): this is missing PodSandboxConfig!!!
// we should/could find a way to retrieve it from the fs and set it here
})
if err != nil {
return err
}
fmt.Println(r.ContainerId)
return nil
}
// StartContainer sends a StartContainerRequest to the server, and parses
// the returned StartContainerResponse.
func StartContainer(client pb.RuntimeServiceClient, ID string) error {
if ID == "" {
return fmt.Errorf("ID cannot be empty")
}
_, err := client.StartContainer(context.Background(), &pb.StartContainerRequest{
ContainerId: ID,
})
if err != nil {
return err
}
fmt.Println(ID)
return nil
}
// StopContainer sends a StopContainerRequest to the server, and parses
// the returned StopContainerResponse.
func StopContainer(client pb.RuntimeServiceClient, ID string, timeout int64) error {
if ID == "" {
return fmt.Errorf("ID cannot be empty")
}
_, err := client.StopContainer(context.Background(), &pb.StopContainerRequest{
ContainerId: ID,
Timeout: timeout,
})
if err != nil {
return err
}
fmt.Println(ID)
return nil
}
// RemoveContainer sends a RemoveContainerRequest to the server, and parses
// the returned RemoveContainerResponse.
func RemoveContainer(client pb.RuntimeServiceClient, ID string) error {
if ID == "" {
return fmt.Errorf("ID cannot be empty")
}
_, err := client.RemoveContainer(context.Background(), &pb.RemoveContainerRequest{
ContainerId: ID,
})
if err != nil {
return err
}
fmt.Println(ID)
return nil
}
// ContainerStatus sends a ContainerStatusRequest to the server, and parses
// the returned ContainerStatusResponse.
func ContainerStatus(client pb.RuntimeServiceClient, ID string) error {
if ID == "" {
return fmt.Errorf("ID cannot be empty")
}
r, err := client.ContainerStatus(context.Background(), &pb.ContainerStatusRequest{
ContainerId: ID})
if err != nil {
return err
}
fmt.Printf("ID: %s\n", r.Status.Id)
if r.Status.Metadata != nil {
if r.Status.Metadata.Name != "" {
fmt.Printf("Name: %s\n", r.Status.Metadata.Name)
}
fmt.Printf("Attempt: %v\n", r.Status.Metadata.Attempt)
}
// TODO(mzylowski): print it prettier
fmt.Printf("Status: %s\n", r.Status.State)
ctm := time.Unix(0, r.Status.CreatedAt)
fmt.Printf("Created: %v\n", ctm)
stm := time.Unix(0, r.Status.StartedAt)
fmt.Printf("Started: %v\n", stm)
ftm := time.Unix(0, r.Status.FinishedAt)
fmt.Printf("Finished: %v\n", ftm)
fmt.Printf("Exit Code: %v\n", r.Status.ExitCode)
fmt.Printf("Reason: %v\n", r.Status.Reason)
if r.Status.Image != nil {
fmt.Printf("Image: %v\n", r.Status.Image.Image)
}
//
// TODO: https://github.com/kubernetes-incubator/cri-o/issues/531
//
//fmt.Printf("ImageRef: %v\n", r.Status.ImageRef)
return nil
}
// ExecSync sends an ExecSyncRequest to the server, and parses
// the returned ExecSyncResponse.
func ExecSync(client pb.RuntimeServiceClient, ID string, cmd []string, timeout int64) error {
if ID == "" {
return fmt.Errorf("ID cannot be empty")
}
r, err := client.ExecSync(context.Background(), &pb.ExecSyncRequest{
ContainerId: ID,
Cmd: cmd,
Timeout: timeout,
})
if err != nil {
return err
}
fmt.Println("Stdout:")
fmt.Println(string(r.Stdout))
fmt.Println("Stderr:")
fmt.Println(string(r.Stderr))
fmt.Printf("Exit code: %v\n", r.ExitCode)
return nil
}
// Exec sends an ExecRequest to the server, and parses
// the returned ExecResponse.
func Exec(client pb.RuntimeServiceClient, ID string, tty bool, stdin bool, urlOnly bool, cmd []string) error {
if ID == "" {
return fmt.Errorf("ID cannot be empty")
}
r, err := client.Exec(context.Background(), &pb.ExecRequest{
ContainerId: ID,
Cmd: cmd,
Tty: tty,
Stdin: stdin,
})
if err != nil {
return err
}
if urlOnly {
fmt.Println("URL:")
fmt.Println(r.Url)
return nil
}
execURL, err := url.Parse(r.Url)
if err != nil {
return err
}
streamExec, err := remotecommand.NewSPDYExecutor(&restclient.Config{}, "GET", execURL)
if err != nil {
return err
}
options := remotecommand.StreamOptions{
Stdout: os.Stdout,
Stderr: os.Stderr,
Tty: tty,
}
if stdin {
options.Stdin = os.Stdin
}
return streamExec.Stream(options)
}
// ListContainers sends a ListContainerRequest to the server, and parses
// the returned ListContainerResponse.
func ListContainers(client pb.RuntimeServiceClient, opts listOptions) error {
filter := &pb.ContainerFilter{}
if opts.id != "" {
filter.Id = opts.id
}
if opts.podID != "" {
filter.PodSandboxId = opts.podID
}
if opts.state != "" {
st := &pb.ContainerStateValue{}
st.State = pb.ContainerState_CONTAINER_UNKNOWN
switch opts.state {
case "created":
st.State = pb.ContainerState_CONTAINER_CREATED
filter.State = st
case "running":
st.State = pb.ContainerState_CONTAINER_RUNNING
filter.State = st
case "stopped":
st.State = pb.ContainerState_CONTAINER_EXITED
filter.State = st
default:
log.Fatalf("--state should be one of created, running or stopped")
}
}
if opts.labels != nil {
filter.LabelSelector = opts.labels
}
r, err := client.ListContainers(context.Background(), &pb.ListContainersRequest{
Filter: filter,
})
if err != nil {
return err
}
for _, c := range r.GetContainers() {
if opts.quiet {
fmt.Println(c.Id)
continue
}
fmt.Printf("ID: %s\n", c.Id)
fmt.Printf("Pod: %s\n", c.PodSandboxId)
if c.Metadata != nil {
if c.Metadata.Name != "" {
fmt.Printf("Name: %s\n", c.Metadata.Name)
}
fmt.Printf("Attempt: %v\n", c.Metadata.Attempt)
}
fmt.Printf("Status: %s\n", c.State)
if c.Image != nil {
fmt.Printf("Image: %s\n", c.Image.Image)
}
ctm := time.Unix(0, c.CreatedAt)
fmt.Printf("Created: %v\n", ctm)
if c.Labels != nil {
fmt.Println("Labels:")
for _, k := range getSortedKeys(c.Labels) {
fmt.Printf("\t%s -> %s\n", k, c.Labels[k])
}
}
if c.Annotations != nil {
fmt.Println("Annotations:")
for _, k := range getSortedKeys(c.Annotations) {
fmt.Printf("\t%s -> %s\n", k, c.Annotations[k])
}
}
fmt.Println()
}
return nil
}
var inspectContainerCommand = cli.Command{
Name: "inspect",
Usage: "get container info from crio daemon",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "id of the container",
},
},
Action: func(context *cli.Context) error {
ID := context.String("id")
if ID == "" {
return fmt.Errorf("ID cannot be empty")
}
c, err := client.New(context.GlobalString("connect"))
if err != nil {
return err
}
cInfo, err := c.ContainerInfo(ID)
if err != nil {
return err
}
jsonBytes, err := json.MarshalIndent(cInfo, "", " ")
if err != nil {
return err
}
fmt.Println(string(jsonBytes))
return nil
},
}

View File

@ -1,173 +0,0 @@
package main
import (
"fmt"
"github.com/urfave/cli"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
)
var imageCommand = cli.Command{
Name: "image",
Subcommands: []cli.Command{
pullImageCommand,
listImageCommand,
imageStatusCommand,
removeImageCommand,
},
}
var pullImageCommand = cli.Command{
Name: "pull",
Usage: "pull an image",
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewImageServiceClient(conn)
_, err = PullImage(client, context.Args().Get(0))
if err != nil {
return fmt.Errorf("pulling image failed: %v", err)
}
return nil
},
}
var listImageCommand = cli.Command{
Name: "list",
Usage: "list images",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "quiet",
Usage: "list only image IDs",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewImageServiceClient(conn)
r, err := ListImages(client, context.Args().Get(0))
if err != nil {
return fmt.Errorf("listing images failed: %v", err)
}
quiet := context.Bool("quiet")
for _, image := range r.Images {
if quiet {
fmt.Printf("%s\n", image.Id)
continue
}
fmt.Printf("ID: %s\n", image.Id)
for _, tag := range image.RepoTags {
fmt.Printf("Tag: %s\n", tag)
}
for _, digest := range image.RepoDigests {
fmt.Printf("Digest: %s\n", digest)
}
if image.Size_ != 0 {
fmt.Printf("Size: %d\n", image.Size_)
}
}
return nil
},
}
var imageStatusCommand = cli.Command{
Name: "status",
Usage: "return the status of an image",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Usage: "id of the image",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewImageServiceClient(conn)
r, err := ImageStatus(client, context.String("id"))
if err != nil {
return fmt.Errorf("image status request failed: %v", err)
}
image := r.Image
if image == nil {
return fmt.Errorf("no such image present")
}
fmt.Printf("ID: %s\n", image.Id)
for _, tag := range image.RepoTags {
fmt.Printf("Tag: %s\n", tag)
}
for _, digest := range image.RepoDigests {
fmt.Printf("Digest: %s\n", digest)
}
fmt.Printf("Size: %d\n", image.Size_)
return nil
},
}
var removeImageCommand = cli.Command{
Name: "remove",
Usage: "remove an image",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "id of the image",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewImageServiceClient(conn)
_, err = RemoveImage(client, context.String("id"))
if err != nil {
return fmt.Errorf("removing the image failed: %v", err)
}
return nil
},
}
// PullImage sends a PullImageRequest to the server, and parses
// the returned PullImageResponse.
func PullImage(client pb.ImageServiceClient, image string) (*pb.PullImageResponse, error) {
return client.PullImage(context.Background(), &pb.PullImageRequest{Image: &pb.ImageSpec{Image: image}})
}
// ListImages sends a ListImagesRequest to the server, and parses
// the returned ListImagesResponse.
func ListImages(client pb.ImageServiceClient, image string) (*pb.ListImagesResponse, error) {
return client.ListImages(context.Background(), &pb.ListImagesRequest{Filter: &pb.ImageFilter{Image: &pb.ImageSpec{Image: image}}})
}
// ImageStatus sends an ImageStatusRequest to the server, and parses
// the returned ImageStatusResponse.
func ImageStatus(client pb.ImageServiceClient, image string) (*pb.ImageStatusResponse, error) {
return client.ImageStatus(context.Background(), &pb.ImageStatusRequest{Image: &pb.ImageSpec{Image: image}})
}
// RemoveImage sends a RemoveImageRequest to the server, and parses
// the returned RemoveImageResponse.
func RemoveImage(client pb.ImageServiceClient, image string) (*pb.RemoveImageResponse, error) {
if image == "" {
return nil, fmt.Errorf("ID cannot be empty")
}
return client.RemoveImage(context.Background(), &pb.RemoveImageRequest{Image: &pb.ImageSpec{Image: image}})
}

View File

@ -1,31 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"github.com/kubernetes-incubator/cri-o/client"
"github.com/urfave/cli"
)
var infoCommand = cli.Command{
Name: "info",
Usage: "get crio daemon info",
Action: func(context *cli.Context) error {
c, err := client.New(context.GlobalString("connect"))
if err != nil {
return err
}
di, err := c.DaemonInfo()
if err != nil {
return err
}
jsonBytes, err := json.MarshalIndent(di, "", " ")
if err != nil {
return err
}
fmt.Println(string(jsonBytes))
return nil
},
}

View File

@ -1,113 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"net"
"os"
"strings"
"time"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"google.golang.org/grpc"
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
)
// This is populated by the Makefile from the VERSION file
// in the repository
var version = ""
// gitCommit is the commit that the binary is being built from.
// It will be populated by the Makefile.
var gitCommit = ""
func getClientConnection(context *cli.Context) (*grpc.ClientConn, error) {
conn, err := grpc.Dial(context.GlobalString("connect"), grpc.WithInsecure(), grpc.WithTimeout(context.GlobalDuration("timeout")),
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("unix", addr, timeout)
}))
if err != nil {
return nil, fmt.Errorf("failed to connect: %v", err)
}
return conn, nil
}
func openFile(path string) (*os.File, error) {
f, err := os.Open(path)
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("config at %s not found", path)
}
return nil, err
}
return f, nil
}
func loadPodSandboxConfig(path string) (*pb.PodSandboxConfig, error) {
f, err := openFile(path)
if err != nil {
return nil, err
}
defer f.Close()
var config pb.PodSandboxConfig
if err := json.NewDecoder(f).Decode(&config); err != nil {
return nil, err
}
return &config, nil
}
func loadContainerConfig(path string) (*pb.ContainerConfig, error) {
f, err := openFile(path)
if err != nil {
return nil, err
}
defer f.Close()
var config pb.ContainerConfig
if err := json.NewDecoder(f).Decode(&config); err != nil {
return nil, err
}
return &config, nil
}
func main() {
app := cli.NewApp()
var v []string
if version != "" {
v = append(v, version)
}
if gitCommit != "" {
v = append(v, fmt.Sprintf("commit: %s", gitCommit))
}
app.Name = "crioctl"
app.Usage = "client for crio"
app.Version = strings.Join(v, "\n")
app.Commands = []cli.Command{
podSandboxCommand,
containerCommand,
runtimeVersionCommand,
imageCommand,
infoCommand,
}
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "connect",
Value: "/var/run/crio.sock",
Usage: "Socket to connect to",
},
cli.DurationFlag{
Name: "timeout",
Value: 10 * time.Second,
Usage: "Timeout of connecting to server",
},
}
if err := app.Run(os.Args); err != nil {
logrus.Fatal(err)
}
}

View File

@ -1,386 +0,0 @@
package main
import (
"fmt"
"log"
"sort"
"strings"
"time"
"github.com/urfave/cli"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
)
var podSandboxCommand = cli.Command{
Name: "pod",
Subcommands: []cli.Command{
runPodSandboxCommand,
stopPodSandboxCommand,
removePodSandboxCommand,
podSandboxStatusCommand,
listPodSandboxCommand,
},
}
var runPodSandboxCommand = cli.Command{
Name: "run",
Usage: "run a pod",
Flags: []cli.Flag{
cli.StringFlag{
Name: "config",
Value: "",
Usage: "the path of a pod sandbox config file",
},
cli.StringFlag{
Name: "name",
Value: "",
Usage: "the name of the pod sandbox",
},
cli.StringSliceFlag{
Name: "label",
Usage: "add key=value labels to the container",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
opts := createOptions{
configPath: context.String("config"),
name: context.String("name"),
labels: make(map[string]string),
}
for _, l := range context.StringSlice("label") {
pair := strings.Split(l, "=")
if len(pair) != 2 {
return fmt.Errorf("incorrectly specified label: %v", l)
}
opts.labels[pair[0]] = pair[1]
}
// Test RuntimeServiceClient.RunPodSandbox
err = RunPodSandbox(client, opts)
if err != nil {
return fmt.Errorf("Creating the pod sandbox failed: %v", err)
}
return nil
},
}
var stopPodSandboxCommand = cli.Command{
Name: "stop",
Usage: "stop a pod sandbox",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "id of the pod sandbox",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
err = StopPodSandbox(client, context.String("id"))
if err != nil {
return fmt.Errorf("stopping the pod sandbox failed: %v", err)
}
return nil
},
}
var removePodSandboxCommand = cli.Command{
Name: "remove",
Usage: "remove a pod sandbox",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "id of the pod sandbox",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
err = RemovePodSandbox(client, context.String("id"))
if err != nil {
return fmt.Errorf("removing the pod sandbox failed: %v", err)
}
return nil
},
}
var podSandboxStatusCommand = cli.Command{
Name: "status",
Usage: "return the status of a pod",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "id of the pod",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
err = PodSandboxStatus(client, context.String("id"))
if err != nil {
return fmt.Errorf("getting the pod sandbox status failed: %v", err)
}
return nil
},
}
var listPodSandboxCommand = cli.Command{
Name: "list",
Usage: "list pod sandboxes",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id",
Value: "",
Usage: "filter by pod sandbox id",
},
cli.StringFlag{
Name: "state",
Value: "",
Usage: "filter by pod sandbox state",
},
cli.StringSliceFlag{
Name: "label",
Usage: "filter by key=value label",
},
cli.BoolFlag{
Name: "quiet",
Usage: "list only pod IDs",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
opts := listOptions{
id: context.String("id"),
state: context.String("state"),
quiet: context.Bool("quiet"),
labels: make(map[string]string),
}
for _, l := range context.StringSlice("label") {
pair := strings.Split(l, "=")
if len(pair) != 2 {
return fmt.Errorf("incorrectly specified label: %v", l)
}
opts.labels[pair[0]] = pair[1]
}
err = ListPodSandboxes(client, opts)
if err != nil {
return fmt.Errorf("listing pod sandboxes failed: %v", err)
}
return nil
},
}
// RunPodSandbox sends a RunPodSandboxRequest to the server, and parses
// the returned RunPodSandboxResponse.
func RunPodSandbox(client pb.RuntimeServiceClient, opts createOptions) error {
config, err := loadPodSandboxConfig(opts.configPath)
if err != nil {
return err
}
// Override the name by the one specified through CLI
if opts.name != "" {
config.Metadata.Name = opts.name
}
for k, v := range opts.labels {
config.Labels[k] = v
}
r, err := client.RunPodSandbox(context.Background(), &pb.RunPodSandboxRequest{Config: config})
if err != nil {
return err
}
fmt.Println(r.PodSandboxId)
return nil
}
// StopPodSandbox sends a StopPodSandboxRequest to the server, and parses
// the returned StopPodSandboxResponse.
func StopPodSandbox(client pb.RuntimeServiceClient, ID string) error {
if ID == "" {
return fmt.Errorf("ID cannot be empty")
}
_, err := client.StopPodSandbox(context.Background(), &pb.StopPodSandboxRequest{PodSandboxId: ID})
if err != nil {
return err
}
fmt.Println(ID)
return nil
}
// RemovePodSandbox sends a RemovePodSandboxRequest to the server, and parses
// the returned RemovePodSandboxResponse.
func RemovePodSandbox(client pb.RuntimeServiceClient, ID string) error {
if ID == "" {
return fmt.Errorf("ID cannot be empty")
}
_, err := client.RemovePodSandbox(context.Background(), &pb.RemovePodSandboxRequest{PodSandboxId: ID})
if err != nil {
return err
}
fmt.Println(ID)
return nil
}
// PodSandboxStatus sends a PodSandboxStatusRequest to the server, and parses
// the returned PodSandboxStatusResponse.
func PodSandboxStatus(client pb.RuntimeServiceClient, ID string) error {
if ID == "" {
return fmt.Errorf("ID cannot be empty")
}
r, err := client.PodSandboxStatus(context.Background(), &pb.PodSandboxStatusRequest{PodSandboxId: ID})
if err != nil {
return err
}
fmt.Printf("ID: %s\n", r.Status.Id)
if r.Status.Metadata != nil {
if r.Status.Metadata.Name != "" {
fmt.Printf("Name: %s\n", r.Status.Metadata.Name)
}
if r.Status.Metadata.Uid != "" {
fmt.Printf("UID: %s\n", r.Status.Metadata.Uid)
}
if r.Status.Metadata.Namespace != "" {
fmt.Printf("Namespace: %s\n", r.Status.Metadata.Namespace)
}
fmt.Printf("Attempt: %v\n", r.Status.Metadata.Attempt)
}
fmt.Printf("Status: %s\n", r.Status.State)
ctm := time.Unix(0, r.Status.CreatedAt)
fmt.Printf("Created: %v\n", ctm)
if r.Status.Network != nil {
fmt.Printf("IP Address: %v\n", r.Status.Network.Ip)
}
if r.Status.Labels != nil {
fmt.Println("Labels:")
for _, k := range getSortedKeys(r.Status.Labels) {
fmt.Printf("\t%s -> %s\n", k, r.Status.Labels[k])
}
}
if r.Status.Annotations != nil {
fmt.Println("Annotations:")
for _, k := range getSortedKeys(r.Status.Annotations) {
fmt.Printf("\t%s -> %s\n", k, r.Status.Annotations[k])
}
}
return nil
}
// ListPodSandboxes sends a ListPodSandboxRequest to the server, and parses
// the returned ListPodSandboxResponse.
func ListPodSandboxes(client pb.RuntimeServiceClient, opts listOptions) error {
filter := &pb.PodSandboxFilter{}
if opts.id != "" {
filter.Id = opts.id
}
if opts.state != "" {
st := &pb.PodSandboxStateValue{}
st.State = pb.PodSandboxState_SANDBOX_NOTREADY
switch opts.state {
case "ready":
st.State = pb.PodSandboxState_SANDBOX_READY
filter.State = st
case "notready":
st.State = pb.PodSandboxState_SANDBOX_NOTREADY
filter.State = st
default:
log.Fatalf("--state should be ready or notready")
}
}
if opts.labels != nil {
filter.LabelSelector = opts.labels
}
r, err := client.ListPodSandbox(context.Background(), &pb.ListPodSandboxRequest{
Filter: filter,
})
if err != nil {
return err
}
for _, pod := range r.Items {
if opts.quiet {
fmt.Println(pod.Id)
continue
}
fmt.Printf("ID: %s\n", pod.Id)
if pod.Metadata != nil {
if pod.Metadata.Name != "" {
fmt.Printf("Name: %s\n", pod.Metadata.Name)
}
if pod.Metadata.Uid != "" {
fmt.Printf("UID: %s\n", pod.Metadata.Uid)
}
if pod.Metadata.Namespace != "" {
fmt.Printf("Namespace: %s\n", pod.Metadata.Namespace)
}
fmt.Printf("Attempt: %v\n", pod.Metadata.Attempt)
}
fmt.Printf("Status: %s\n", pod.State)
ctm := time.Unix(0, pod.CreatedAt)
fmt.Printf("Created: %v\n", ctm)
if pod.Labels != nil {
fmt.Println("Labels:")
for _, k := range getSortedKeys(pod.Labels) {
fmt.Printf("\t%s -> %s\n", k, pod.Labels[k])
}
}
if pod.Annotations != nil {
fmt.Println("Annotations:")
for _, k := range getSortedKeys(pod.Annotations) {
fmt.Printf("\t%s -> %s\n", k, pod.Annotations[k])
}
}
fmt.Println()
}
return nil
}
func getSortedKeys(m map[string]string) []string {
var keys []string
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}

View File

@ -1,41 +0,0 @@
package main
import (
"fmt"
"github.com/urfave/cli"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
)
var runtimeVersionCommand = cli.Command{
Name: "runtimeversion",
Usage: "get runtime version information",
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection(context)
if err != nil {
return fmt.Errorf("failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
// Test RuntimeServiceClient.Version
version := "v1alpha1"
err = Version(client, version)
if err != nil {
return fmt.Errorf("Getting the runtime version failed: %v", err)
}
return nil
},
}
// Version sends a VersionRequest to the server, and parses the returned VersionResponse.
func Version(client pb.RuntimeServiceClient, version string) error {
r, err := client.Version(context.Background(), &pb.VersionRequest{Version: version})
if err != nil {
return err
}
fmt.Printf("VersionResponse: Version: %s, RuntimeName: %s, RuntimeVersion: %s, RuntimeApiVersion: %s\n", r.Version, r.RuntimeName, r.RuntimeVersion, r.RuntimeApiVersion)
return nil
}

View File

@ -1,55 +1,3 @@
## Kubernetes Community Code of Conduct
# Kubernetes Community Code of Conduct
### Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering
an open and welcoming community, we pledge to respect all people who contribute
through reporting issues, posting feature requests, updating documentation,
submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for
everyone, regardless of level of experience, gender, gender identity and expression,
sexual orientation, disability, personal appearance, body size, race, ethnicity, age,
religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery.
* Personal attacks.
* Trolling or insulting/derogatory comments.
* Public or private harassment.
* Publishing other's private information, such as physical or electronic addresses,
without explicit permission.
* Other unethical or unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are not
aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers
commit themselves to fairly and consistently applying these principles to every aspect
of managing this project. Project maintainers who do not follow or enforce the Code of
Conduct may be permanently removed from the project team.
This code of conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a Kubernetes maintainer, Sarah Novotny <sarahnovotny@google.com>, and/or Dan Kohn <dan@linuxfoundation.org>.
This Code of Conduct is adapted from the Contributor Covenant
(http://contributor-covenant.org), version 1.2.0, available at
http://contributor-covenant.org/version/1/2/0/
### Kubernetes Events Code of Conduct
Kubernetes events are working conferences intended for professional networking and collaboration in the
Kubernetes community. Attendees are expected to behave according to professional standards and in accordance
with their employer's policies on appropriate workplace behavior.
While at Kubernetes events or related social networking opportunities, attendees should not engage in
discriminatory or offensive speech or actions regarding gender, sexuality, race, or religion. Speakers should
be especially aware of these concerns.
The Kubernetes team does not condone any statements by speakers contrary to these standards. The Kubernetes
team reserves the right to deny entrance and/or eject from an event (without refund) any individual found to
be engaging in discriminatory or offensive speech or actions.
Please bring any concerns to the immediate attention of the Kubernetes event staff.
Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md)

View File

@ -12,7 +12,6 @@
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/eventfd.h>
#include <sys/stat.h>
@ -296,7 +295,6 @@ const char *stdpipe_name(stdpipe_t pipe)
static int write_k8s_log(int fd, stdpipe_t pipe, const char *buf, ssize_t buflen)
{
char tsbuf[TSBUFLEN];
static stdpipe_t trailing_line = NO_PIPE;
writev_buffer_t bufv = {0};
static int64_t bytes_written = 0;
int64_t bytes_to_be_written = 0;
@ -313,35 +311,22 @@ static int write_k8s_log(int fd, stdpipe_t pipe, const char *buf, ssize_t buflen
while (buflen > 0) {
const char *line_end = NULL;
ptrdiff_t line_len = 0;
bool insert_newline = FALSE;
bool insert_timestamp = FALSE;
bool partial = FALSE;
/* Find the end of the line, or alternatively the end of the buffer. */
line_end = memchr(buf, '\n', buflen);
if (line_end == NULL)
if (line_end == NULL) {
line_end = &buf[buflen-1];
partial = TRUE;
}
line_len = line_end - buf + 1;
bytes_to_be_written = line_len;
if (trailing_line != pipe) {
/*
* Write the (timestamp, stream) tuple if there isn't any trailing
* output from the previous line (or if there is trailing output but
* the current buffer being printed is from a different pipe).
*/
insert_timestamp = TRUE;
bytes_to_be_written += (TSBUFLEN - 1);
/*
* If there was a trailing line from a different pipe, prepend a
* newline to split it properly. This technically breaks the flow
* of the previous line (adding a newline in the log where there
* wasn't one output) but without modifying the file in a
* non-append-only way there's not much we can do.
*/
if (trailing_line != NO_PIPE) {
insert_newline = TRUE;
bytes_to_be_written += 1;
}
/* This is line_len bytes + TSBUFLEN - 1 + 2 (- 1 is for ignoring \0). */
bytes_to_be_written = line_len + TSBUFLEN + 1;
/* If partial, then we add a \n */
if (partial) {
bytes_to_be_written += 1;
}
/*
@ -351,8 +336,6 @@ static int write_k8s_log(int fd, stdpipe_t pipe, const char *buf, ssize_t buflen
*/
if ((opt_log_size_max > 0) && (bytes_written + bytes_to_be_written) > opt_log_size_max) {
ninfo("Creating new log file");
insert_newline = FALSE;
insert_timestamp = TRUE;
bytes_written = 0;
/* Close the existing fd */
@ -366,22 +349,25 @@ static int write_k8s_log(int fd, stdpipe_t pipe, const char *buf, ssize_t buflen
/* Open the log path file again */
log_fd = open(opt_log_path, O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC, 0600);
if (log_fd < 0)
pexit("Failed to open log file");
pexit("Failed to open log file %s: %s", opt_log_path, strerror(errno));
fd = log_fd;
}
/* Output a newline */
if (insert_newline) {
if (writev_buffer_append_segment(fd, &bufv, "\n", -1) < 0) {
nwarn("failed to write newline to log");
goto next;
}
/* Output the timestamp */
if (writev_buffer_append_segment(fd, &bufv, tsbuf, -1) < 0) {
nwarn("failed to write (timestamp, stream) to log");
goto next;
}
/* Output a timestamp */
if (insert_timestamp) {
if (writev_buffer_append_segment(fd, &bufv, tsbuf, -1) < 0) {
nwarn("failed to write (timestamp, stream) to log");
/* Output log tag for partial or newline */
if (partial) {
if (writev_buffer_append_segment(fd, &bufv, "P ", -1) < 0) {
nwarn("failed to write partial log tag");
goto next;
}
} else {
if (writev_buffer_append_segment(fd, &bufv, "F ", -1) < 0) {
nwarn("failed to write end log tag");
goto next;
}
}
@ -392,11 +378,15 @@ static int write_k8s_log(int fd, stdpipe_t pipe, const char *buf, ssize_t buflen
goto next;
}
/* Output a newline for partial */
if (partial) {
if (writev_buffer_append_segment(fd, &bufv, "\n", -1) < 0) {
nwarn("failed to write newline to log");
goto next;
}
}
bytes_written += bytes_to_be_written;
/* If we did not output a full line, then we are a trailing_line. */
trailing_line = (*line_end == '\n') ? NO_PIPE : pipe;
next:
/* Update the head of the buffer remaining to output. */
buf += line_len;
@ -1130,6 +1120,8 @@ int main(int argc, char *argv[])
if (opt_runtime_path == NULL)
nexit("Runtime path not provided. Use --runtime");
if (access(opt_runtime_path, X_OK) < 0)
pexit("Runtime path %s is not valid: %s", opt_runtime_path, strerror(errno));
if (!opt_exec && opt_exit_dir == NULL)
nexit("Container exit directory not provided. Use --exit-dir");

View File

@ -1,14 +0,0 @@
.PHONY: dist
dist: crio.spec
spectool -g crio.spec
.PHONY: rpm
rpm: dist
rpmbuild --define "_sourcedir `pwd`" --define "_specdir `pwd`" \
--define "_rpmdir `pwd`" --define "_srcrpmdir `pwd`" -ba crio.spec
all: rpm
clean:
rm -f *rpm *gz
rm -rf x86_64

View File

@ -1,76 +0,0 @@
%define debug_package %{nil}
%global provider github
%global provider_tld com
%global project kubernetes-incubator
%global repo cri-o
%global Name crio
# https://github.com/kubernetes-incubator/cri-o
%global provider_prefix %{provider}.%{provider_tld}/%{project}/%{repo}
%global import_path %{provider_prefix}
%global commit 8ba639952a95f2e24cc98987689138b67545576c
%global shortcommit %(c=%{commit}; echo ${c:0:7})
Name: %{Name}
Version: 0.0.1
Release: 1.git%{shortcommit}%{?dist}
Summary: Kubelet Container Runtime Interface (CRI) for OCI runtimes.
Group: Applications/Text
License: Apache 2.0
URL: https://%{provider_prefix}
Source0: https://%{provider_prefix}/archive/%{commit}/%{repo}-%{shortcommit}.tar.gz
Provides: %{repo}
BuildRequires: golang-github-cpuguy83-go-md2man
%description
The crio package provides an implementation of the
Kubelet Container Runtime Interface (CRI) using OCI conformant runtimes.
crio provides following functionalities:
Support multiple image formats including the existing Docker image format
Support for multiple means to download images including trust & image verification
Container image management (managing image layers, overlay filesystems, etc)
Container process lifecycle management
Monitoring and logging required to satisfy the CRI
Resource isolation as required by the CRI
%prep
%setup -q -n %{repo}-%{commit}
%build
make all
%install
%make_install
%make_install install.systemd
#define license tag if not already defined
%{!?_licensedir:%global license %doc}
%files
%{_bindir}/crio
%{_bindir}/crioctl
%{_mandir}/man5/crio.conf.5*
%{_mandir}/man8/crio.8*
%{_sysconfdir}/crio.conf
%{_sysconfdir}/seccomp.json
%dir /%{_libexecdir}/crio
/%{_libexecdir}/crio/conmon
/%{_libexecdir}/crio/pause
%{_unitdir}/crio.service
%doc README.md
%license LICENSE
%dir /usr/share/oci-umount/oci-umount.d
/usr/share/oci-umount/oci-umount.d/cri-umount.conf
%preun
%systemd_preun %{Name}
%postun
%systemd_postun_with_restart %{Name}
%changelog
* Mon Oct 31 2016 Dan Walsh <dwalsh@redhat.com> - 0.0.1
- Initial RPM release

View File

@ -0,0 +1,29 @@
FROM centos
ENV VERSION=0 RELEASE=1 ARCH=x86_64
LABEL com.redhat.component="cri-o" \
name="$FGC/cri-o" \
version="$VERSION" \
release="$RELEASE.$DISTTAG" \
architecture="$ARCH" \
usage="atomic install --system --system-package=no crio && systemctl start crio" \
summary="The cri-o daemon as a system container." \
maintainer="Yu Qi Zhang <jzehrarnyg@gmail.com>" \
atomic.type="system"
RUN yum-config-manager --nogpgcheck --add-repo https://cbs.centos.org/repos/virt7-container-common-candidate/x86_64/os/ && \
yum install --disablerepo=extras --nogpgcheck --setopt=tsflags=nodocs -y iptables cri-o socat iproute runc && \
rpm -V iptables cri-o iproute runc && \
yum clean all && \
mkdir -p /exports/hostfs/etc/crio /exports/hostfs/opt/cni/bin/ /exports/hostfs/var/lib/containers/storage/ && \
cp /etc/crio/* /exports/hostfs/etc/crio && \
if test -e /usr/libexec/cni; then cp -Lr /usr/libexec/cni/* /exports/hostfs/opt/cni/bin/; fi
RUN sed -i '/storage_option =/s/.*/&\n"overlay.override_kernel_check=1",/' /exports/hostfs/etc/crio/crio.conf
COPY manifest.json tmpfiles.template config.json.template service.template /exports/
COPY set_mounts.sh /
COPY run.sh /usr/bin/
CMD ["/usr/bin/run.sh"]

View File

@ -0,0 +1,57 @@
# cri-o
This is the cri-o daemon as a system container.
## Building the image from source:
```
# git clone https://github.com/projectatomic/atomic-system-containers
# cd atomic-system-containers/cri-o
# docker build -t crio .
```
## Running the system container, with the atomic CLI:
Pull from registry into ostree:
```
# atomic pull --storage ostree $REGISTRY/crio
```
Or alternatively, pull from local docker:
```
# atomic pull --storage ostree docker:crio:latest
```
Install the container:
Currently we recommend using --system-package=no to avoid having rpmbuild create an rpm file
during installation. This flag will tell the atomic CLI to fall back to copying files to the
host instead.
```
# atomic install --system --system-package=no --name=crio ($REGISTRY)/crio
```
Start as a systemd service:
```
# systemctl start crio
```
Stopping the service
```
# systemctl stop crio
```
Removing the container
```
# atomic uninstall crio
```
## Binary version
You can find the image automatically built as: registry.centos.org/projectatomic/cri-o:latest

View File

@ -0,0 +1,41 @@
# This is for the purpose of building containers on the CentOS Community Container
# Pipeline. The containers are built, tested and delivered to registry.centos.org and
# lifecycled as well. A corresponding entry must exist in the container index itself,
# located at https://github.com/CentOS/container-index/tree/master/index.d
# You can know more at the following links:
# * https://github.com/CentOS/container-pipeline-service/blob/master/README.md
# * https://github.com/CentOS/container-index/blob/master/README.rst
# * https://wiki.centos.org/ContainerPipeline
# This will be part of the name of the container. It should match the job-id in index entry
job-id: cri-o
#the following are optional, can be left blank
#defaults, where applicable are filled in
#nulecule-file : nulecule
# This flag tells the container pipeline to skip user defined tests on their container
test-skip : True
# This is path of the script that initiates the user defined tests. It must be able to
# return an exit code.
test-script : null
# This is the path of custom build script.
build-script : null
# This is the path of the custom delivery script
delivery-script : null
# This flag tells the pipeline to deliver this container to docker hub.
docker-index : True
# This flag can be used to enable or disable the custom delivery
custom-delivery : False
# This flag can be used to enable or disable delivery of container to local registry
local-delivery : True
Upstreams :
- ref :
url :

View File

@ -0,0 +1,427 @@
{
"ociVersion": "1.0.0",
"platform": {
"arch": "amd64",
"os": "linux"
},
"process": {
"args": [
"/usr/bin/run.sh"
],
"capabilities": {
"ambient": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND"
],
"bounding": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND"
],
"effective": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND"
],
"inheritable": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND"
],
"permitted": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND"
]
},
"selinuxLabel": "system_u:system_r:container_runtime_t:s0",
"cwd": "/",
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/root/go/bin",
"TERM=xterm",
"LOG_LEVEL=$LOG_LEVEL",
"NAME=$NAME"
],
"noNewPrivileges": false,
"terminal": false,
"user": {
"gid": 0,
"uid": 0
}
},
"root": {
"path": "rootfs",
"readonly": true
},
"hooks": {},
"linux": {
"namespaces": [
{
"type": "mount"
}
],
"resources": {
"devices": [
{
"access": "rwm",
"allow": true
}
]
},
"rootfsPropagation": "private"
},
"mounts": [
{
"destination": "/tmp",
"options": [
"private",
"bind",
"rw",
"mode=755"
],
"source": "/tmp",
"type": "bind"
},
{
"destination": "/etc",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/etc",
"type": "bind"
},
{
"destination": "/lib/modules",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/lib/modules",
"type": "bind"
},
{
"destination": "/root",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/root",
"type": "bind"
},
{
"destination": "/home",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/home",
"type": "bind"
},
{
"destination": "/mnt",
"options": [
"rbind",
"rw",
"rprivate",
"mode=755"
],
"source": "/mnt",
"type": "bind"
},
{
"type": "bind",
"source": "${RUN_DIRECTORY}",
"destination": "/run",
"options": [
"rshared",
"rbind",
"rw",
"mode=755"
]
},
{
"type": "bind",
"source": "${RUN_DIRECTORY}/systemd",
"destination": "/run/systemd",
"options": [
"rslave",
"bind",
"rw",
"mode=755"
]
},
{
"destination": "/var/log",
"options": [
"rbind",
"rslave",
"rw"
],
"source": "/var/log",
"type": "bind"
},
{
"destination": "/var/lib",
"options": [
"rbind",
"rprivate",
"rw"
],
"source": "${STATE_DIRECTORY}",
"type": "bind"
},
{
"destination": "/var/lib/containers/storage",
"options": [
"rbind",
"rshared",
"rw"
],
"source": "${VAR_LIB_CONTAINERS_STORAGE}",
"type": "bind"
},
{
"destination": "/var/lib/origin",
"options": [
"rshared",
"bind",
"rw"
],
"source": "${VAR_LIB_ORIGIN}",
"type": "bind"
},
{
"destination": "/var/lib/kubelet",
"options": [
"rshared",
"bind",
"rw"
],
"source": "${VAR_LIB_KUBE}",
"type": "bind"
},
{
"destination": "/opt/cni",
"options": [
"rbind",
"rprivate",
"ro",
"mode=755"
],
"source": "${OPT_CNI}",
"type": "bind"
},
{
"destination": "/dev",
"options": [
"rprivate",
"rbind",
"rw",
"mode=755"
],
"source": "/dev",
"type": "bind"
},
{
"destination": "/sys",
"options": [
"rprivate",
"rbind",
"rw",
"mode=755"
],
"source": "/sys",
"type": "bind"
},
{
"destination": "/proc",
"options": [
"rbind",
"rw",
"mode=755"
],
"source": "/proc",
"type": "proc"
}
]
}

View File

@ -0,0 +1,10 @@
{
"version": "1.0",
"defaultValues": {
"LOG_LEVEL" : "info",
"OPT_CNI" : "/opt/cni",
"VAR_LIB_CONTAINERS_STORAGE" : "/var/lib/containers/storage",
"VAR_LIB_ORIGIN" : "/var/lib/origin",
"VAR_LIB_KUBE" : "/var/lib/kubelet"
}
}

View File

@ -0,0 +1,11 @@
#!/bin/sh
# Ensure that new process maintain this SELinux label
PID=$$
LABEL=`tr -d '\000' < /proc/$PID/attr/current`
printf %s $LABEL > /proc/self/attr/exec
test -e /etc/sysconfig/crio-storage && source /etc/sysconfig/crio-storage
test -e /etc/sysconfig/crio-network && source /etc/sysconfig/crio-network
exec /usr/bin/crio --log-level=$LOG_LEVEL

View File

@ -0,0 +1,20 @@
[Unit]
Description=crio daemon
After=network.target
[Service]
Type=notify
ExecStartPre=/bin/sh $DESTDIR/rootfs/set_mounts.sh
ExecStart=$EXEC_START
ExecStop=$EXEC_STOP
Restart=on-failure
WorkingDirectory=$DESTDIR
RuntimeDirectory=${NAME}
TasksMax=infinity
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,7 @@
#!/bin/sh
findmnt /var/lib/containers/storage > /dev/null || mount --rbind --make-shared /var/lib/containers/storage /var/lib/containers/storage
findmnt /var/lib/origin > /dev/null || mount --bind --make-shared /var/lib/origin /var/lib/origin
findmnt /var/lib/kubelet > /dev/null || mount --bind --make-shared /var/lib/kubelet /var/lib/kubelet
mount --make-shared /run
findmnt /run/systemd > /dev/null || mount --bind --make-rslave /run/systemd /run/systemd

View File

@ -0,0 +1,5 @@
d ${RUN_DIRECTORY}/crio - - - - -
d /etc/crio - - - - -
Z /etc/crio - - - - -
d ${STATE_DIRECTORY}/origin - - - - -
d ${STATE_DIRECTORY}/kubelet - - - - -

View File

@ -0,0 +1,30 @@
FROM registry.fedoraproject.org/fedora:27
ENV VERSION=0 RELEASE=1 ARCH=x86_64
LABEL com.redhat.component="cri-o" \
name="$FGC/cri-o" \
version="$VERSION" \
release="$RELEASE.$DISTTAG" \
architecture="$ARCH" \
usage="atomic install --system --system-package=no crio && systemctl start crio" \
summary="The cri-o daemon as a system container." \
maintainer="Yu Qi Zhang <jzehrarnyg@gmail.com>" \
atomic.type="system"
COPY README.md /
RUN dnf install --enablerepo=updates-testing --setopt=tsflags=nodocs -y iptables cri-o socat iproute runc && \
rpm -V iptables cri-o iproute runc && \
dnf clean all && \
mkdir -p /exports/hostfs/etc/crio /exports/hostfs/opt/cni/bin/ /exports/hostfs/var/lib/containers/storage/ && \
cp /etc/crio/* /exports/hostfs/etc/crio && \
if test -e /usr/libexec/cni; then cp -Lr /usr/libexec/cni/* /exports/hostfs/opt/cni/bin/; fi
RUN sed -i '/storage_option =/s/.*/&\n"overlay.override_kernel_check=1",/' /exports/hostfs/etc/crio/crio.conf
COPY manifest.json tmpfiles.template config.json.template service.template /exports/
COPY set_mounts.sh /
COPY run.sh /usr/bin/
CMD ["/usr/bin/run.sh"]

View File

@ -0,0 +1,53 @@
# cri-o
This is the cri-o daemon as a system container.
## Building the image from source:
```
# git clone https://github.com/projectatomic/atomic-system-containers
# cd atomic-system-containers/cri-o
# docker build -t crio .
```
## Running the system container, with the atomic CLI:
Pull from registry into ostree:
```
# atomic pull --storage ostree $REGISTRY/crio
```
Or alternatively, pull from local docker:
```
# atomic pull --storage ostree docker:crio:latest
```
Install the container:
Currently we recommend using --system-package=no to avoid having rpmbuild create an rpm file
during installation. This flag will tell the atomic CLI to fall back to copying files to the
host instead.
```
# atomic install --system --system-package=no --name=crio ($REGISTRY)/crio
```
Start as a systemd service:
```
# systemctl start crio
```
Stopping the service
```
# systemctl stop crio
```
Removing the container
```
# atomic uninstall crio
```

View File

@ -0,0 +1,432 @@
{
"ociVersion": "1.0.0",
"platform": {
"arch": "amd64",
"os": "linux"
},
"process": {
"args": [
"/usr/bin/run.sh"
],
"selinuxLabel": "system_u:system_r:container_runtime_t:s0",
"capabilities": {
"ambient": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND",
"CAP_AUDIT_READ"
],
"bounding": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND",
"CAP_AUDIT_READ"
],
"effective": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND",
"CAP_AUDIT_READ"
],
"inheritable": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND",
"CAP_AUDIT_READ"
],
"permitted": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND",
"CAP_AUDIT_READ"
]
},
"cwd": "/",
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/root/go/bin",
"TERM=xterm",
"LOG_LEVEL=$LOG_LEVEL",
"NAME=$NAME"
],
"noNewPrivileges": false,
"terminal": false,
"user": {
"gid": 0,
"uid": 0
}
},
"root": {
"path": "rootfs",
"readonly": true
},
"hooks": {},
"linux": {
"namespaces": [
{
"type": "mount"
}
],
"resources": {
"devices": [
{
"access": "rwm",
"allow": true
}
]
},
"rootfsPropagation": "private"
},
"mounts": [
{
"destination": "/tmp",
"options": [
"private",
"bind",
"rw",
"mode=755"
],
"source": "/tmp",
"type": "bind"
},
{
"destination": "/etc",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/etc",
"type": "bind"
},
{
"destination": "/lib/modules",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/lib/modules",
"type": "bind"
},
{
"destination": "/root",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/root",
"type": "bind"
},
{
"destination": "/home",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/home",
"type": "bind"
},
{
"destination": "/mnt",
"options": [
"rbind",
"rw",
"rprivate",
"mode=755"
],
"source": "/mnt",
"type": "bind"
},
{
"type": "bind",
"source": "${RUN_DIRECTORY}",
"destination": "/run",
"options": [
"rshared",
"rbind",
"rw",
"mode=755"
]
},
{
"type": "bind",
"source": "${RUN_DIRECTORY}/systemd",
"destination": "/run/systemd",
"options": [
"rslave",
"bind",
"rw",
"mode=755"
]
},
{
"destination": "/var/log",
"options": [
"rbind",
"rslave",
"rw"
],
"source": "/var/log",
"type": "bind"
},
{
"destination": "/var/lib",
"options": [
"rbind",
"rprivate",
"rw"
],
"source": "${STATE_DIRECTORY}",
"type": "bind"
},
{
"destination": "/var/lib/containers/storage",
"options": [
"rbind",
"rshared",
"rw"
],
"source": "${VAR_LIB_CONTAINERS_STORAGE}",
"type": "bind"
},
{
"destination": "/var/lib/origin",
"options": [
"rshared",
"bind",
"rw"
],
"source": "${VAR_LIB_ORIGIN}",
"type": "bind"
},
{
"destination": "/var/lib/kubelet",
"options": [
"rshared",
"bind",
"rw"
],
"source": "${VAR_LIB_KUBE}",
"type": "bind"
},
{
"destination": "/opt/cni",
"options": [
"rbind",
"rprivate",
"ro",
"mode=755"
],
"source": "${OPT_CNI}",
"type": "bind"
},
{
"destination": "/dev",
"options": [
"rprivate",
"rbind",
"rw",
"mode=755"
],
"source": "/dev",
"type": "bind"
},
{
"destination": "/sys",
"options": [
"rprivate",
"rbind",
"rw",
"mode=755"
],
"source": "/sys",
"type": "bind"
},
{
"destination": "/proc",
"options": [
"rbind",
"rw",
"mode=755"
],
"source": "/proc",
"type": "proc"
}
]
}

View File

@ -0,0 +1,10 @@
{
"version": "1.0",
"defaultValues": {
"LOG_LEVEL" : "info",
"OPT_CNI" : "/opt/cni",
"VAR_LIB_CONTAINERS_STORAGE" : "/var/lib/containers/storage",
"VAR_LIB_ORIGIN" : "/var/lib/origin",
"VAR_LIB_KUBE" : "/var/lib/kubelet"
}
}

View File

@ -0,0 +1,11 @@
#!/bin/sh
# Ensure that new process maintain this SELinux label
PID=$$
LABEL=`tr -d '\000' < /proc/$PID/attr/current`
printf %s $LABEL > /proc/self/attr/exec
test -e /etc/sysconfig/crio-storage && source /etc/sysconfig/crio-storage
test -e /etc/sysconfig/crio-network && source /etc/sysconfig/crio-network
exec /usr/bin/crio --log-level=$LOG_LEVEL

View File

@ -0,0 +1,20 @@
[Unit]
Description=crio daemon
After=network.target
[Service]
Type=notify
ExecStartPre=/bin/sh $DESTDIR/rootfs/set_mounts.sh
ExecStart=$EXEC_START
ExecStop=$EXEC_STOP
Restart=on-failure
WorkingDirectory=$DESTDIR
RuntimeDirectory=${NAME}
TasksMax=infinity
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,7 @@
#!/bin/sh
findmnt /var/lib/containers/storage > /dev/null || mount --rbind --make-shared /var/lib/containers/storage /var/lib/containers/storage
findmnt /var/lib/origin > /dev/null || mount --bind --make-shared /var/lib/origin /var/lib/origin
findmnt /var/lib/kubelet > /dev/null || mount --bind --make-shared /var/lib/kubelet /var/lib/kubelet
mount --make-shared /run
findmnt /run/systemd > /dev/null || mount --bind --make-rslave /run/systemd /run/systemd

View File

@ -0,0 +1,5 @@
d ${RUN_DIRECTORY}/crio - - - - -
d /etc/crio - - - - -
Z /etc/crio - - - - -
d ${STATE_DIRECTORY}/origin - - - - -
d ${STATE_DIRECTORY}/kubelet - - - - -

View File

@ -0,0 +1,41 @@
#oit## This file is managed by the OpenShift Image Tool
#oit## by the OpenShift Continuous Delivery team.
#oit##
#oit## Any yum repos listed in this file will effectively be ignored during CD builds.
#oit## Yum repos must be enabled in the oit configuration files.
#oit## Some aspects of this file may be managed programmatically. For example, the image name, labels (version,
#oit## release, and other), and the base FROM. Changes made directly in distgit may be lost during the next
#oit## reconciliation.
#oit##
FROM rhel7:7-released
RUN \
yum install --setopt=tsflags=nodocs -y socat iptables cri-o iproute runc skopeo-containers container-selinux && \
rpm -V socat iptables cri-o iproute runc skopeo-containers container-selinux && \
yum clean all && \
mkdir -p /exports/hostfs/etc/crio /exports/hostfs/opt/cni/bin/ /exports/hostfs/var/lib/containers/storage/ && \
cp /etc/crio/* /exports/hostfs/etc/crio && \
if test -e /usr/libexec/cni; then cp -Lr /usr/libexec/cni/* /exports/hostfs/opt/cni/bin/; fi
COPY manifest.json tmpfiles.template config.json.template service.template /exports/
COPY set_mounts.sh /
COPY run.sh /usr/bin/
CMD ["/usr/bin/run.sh"]
LABEL \
com.redhat.component="cri-o-docker" \
io.k8s.description="CRI-O is an implementation of the Kubernetes CRI. It is a lightweight, OCI-compliant runtime that is native to kubernetes. CRI-O supports OCI container images and can pull from any container registry." \
maintainer="Jhon Honce <jhonce@redhat.com>" \
name="openshift3/cri-o" \
License="GPLv2+" \
io.k8s.display-name="CRI-O" \
summary="OCI-based implementation of Kubernetes Container Runtime Interface" \
release="0.13.0.0" \
version="v3.8.0" \
architecture="x86_64" \
usage="atomic install --system --system-package=no crio && systemctl start crio" \
vendor="Red Hat" \
io.openshift.tags="cri-o system rhel7" \
atomic.type="system"

View File

@ -0,0 +1,422 @@
{
"ociVersion": "1.0.0",
"platform": {
"arch": "amd64",
"os": "linux"
},
"process": {
"args": [
"/usr/bin/run.sh"
],
"capabilities": {
"ambient": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND"
],
"bounding": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND"
],
"effective": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND"
],
"inheritable": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND"
],
"permitted": [
"CAP_CHOWN",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_DAC_OVERRIDE",
"CAP_MAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND"
]
},
"selinuxLabel": "system_u:system_r:container_runtime_t:s0",
"cwd": "/",
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/root/go/bin",
"TERM=xterm",
"LOG_LEVEL=$LOG_LEVEL",
"NAME=$NAME"
],
"noNewPrivileges": false,
"terminal": false,
"user": {
"gid": 0,
"uid": 0
}
},
"root": {
"path": "rootfs",
"readonly": true
},
"hooks": {},
"linux": {
"namespaces": [{
"type": "mount"
}],
"resources": {
"devices": [{
"access": "rwm",
"allow": true
}]
},
"rootfsPropagation": "private"
},
"mounts": [{
"destination": "/tmp",
"options": [
"private",
"bind",
"rw",
"mode=755"
],
"source": "/tmp",
"type": "bind"
},
{
"destination": "/etc",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/etc",
"type": "bind"
},
{
"destination": "/lib/modules",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/lib/modules",
"type": "bind"
},
{
"destination": "/root",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/root",
"type": "bind"
},
{
"destination": "/home",
"options": [
"rbind",
"rprivate",
"rw",
"mode=755"
],
"source": "/home",
"type": "bind"
},
{
"destination": "/mnt",
"options": [
"rbind",
"rw",
"rprivate",
"mode=755"
],
"source": "/mnt",
"type": "bind"
},
{
"type": "bind",
"source": "${RUN_DIRECTORY}",
"destination": "/run",
"options": [
"rshared",
"rbind",
"rw",
"mode=755"
]
},
{
"type": "bind",
"source": "${RUN_DIRECTORY}/systemd",
"destination": "/run/systemd",
"options": [
"rslave",
"bind",
"rw",
"mode=755"
]
},
{
"destination": "/var/log",
"options": [
"rbind",
"rslave",
"rw"
],
"source": "/var/log",
"type": "bind"
},
{
"destination": "/var/lib",
"options": [
"rbind",
"rprivate",
"rw"
],
"source": "${STATE_DIRECTORY}",
"type": "bind"
},
{
"destination": "/var/lib/containers/storage",
"options": [
"rbind",
"rshared",
"rw"
],
"source": "${VAR_LIB_CONTAINERS_STORAGE}",
"type": "bind"
},
{
"destination": "/var/lib/origin",
"options": [
"rshared",
"bind",
"rw"
],
"source": "${VAR_LIB_ORIGIN}",
"type": "bind"
},
{
"destination": "/var/lib/kubelet",
"options": [
"rshared",
"bind",
"rw"
],
"source": "${VAR_LIB_KUBE}",
"type": "bind"
},
{
"destination": "/opt/cni",
"options": [
"rbind",
"rprivate",
"ro",
"mode=755"
],
"source": "${OPT_CNI}",
"type": "bind"
},
{
"destination": "/dev",
"options": [
"rprivate",
"rbind",
"rw",
"mode=755"
],
"source": "/dev",
"type": "bind"
},
{
"destination": "/sys",
"options": [
"rprivate",
"rbind",
"rw",
"mode=755"
],
"source": "/sys",
"type": "bind"
},
{
"destination": "/proc",
"options": [
"rbind",
"rw",
"mode=755"
],
"source": "/proc",
"type": "proc"
}
]
}

View File

@ -0,0 +1,37 @@
% CRI-O (1) Container Image Pages
% Jhon Honce
% September 7, 2017
# NAME
cri-o - OCI-based implementation of Kubernetes Container Runtime Interface
# DESCRIPTION
CRI-O is an implementation of the Kubernetes CRI. It is a lightweight, OCI-compliant runtime that is native to kubernetes. CRI-O supports OCI container images and can pull from any container registry.
You can find more information on the CRI-O project at <https://github.com/kubernetes-incubator/cri-o/>
# USAGE
Pull from local docker and install system container:
```
# atomic pull --storage ostree docker:openshift3/cri-o:latest
# atomic install --system --system-package=no --name cri-o openshift3/cri-o
```
Start and enable as a systemd service:
```
# systemctl enable --now cri-o
```
Stopping the service
```
# systemctl stop cri-o
```
Removing the container
```
# atomic uninstall cri-o
```
# SEE ALSO
man systemd(1)

View File

@ -0,0 +1,10 @@
{
"version": "1.0",
"defaultValues": {
"LOG_LEVEL": "info",
"OPT_CNI": "/opt/cni",
"VAR_LIB_CONTAINERS_STORAGE": "/var/lib/containers/storage",
"VAR_LIB_ORIGIN": "/var/lib/origin",
"VAR_LIB_KUBE": "/var/lib/kubelet"
}
}

View File

@ -0,0 +1,11 @@
#!/bin/sh
# Ensure that new process maintain this SELinux label
PID=$$
LABEL=`tr -d '\000' < /proc/$PID/attr/current`
printf %s $LABEL > /proc/self/attr/exec
test -e /etc/sysconfig/crio-storage && source /etc/sysconfig/crio-storage
test -e /etc/sysconfig/crio-network && source /etc/sysconfig/crio-network
exec /usr/bin/crio --log-level=$LOG_LEVEL

View File

@ -0,0 +1,20 @@
[Unit]
Description=crio daemon
After=network.target
[Service]
Type=notify
ExecStartPre=/bin/sh $DESTDIR/rootfs/set_mounts.sh
ExecStart=$EXEC_START
ExecStop=$EXEC_STOP
Restart=on-failure
WorkingDirectory=$DESTDIR
RuntimeDirectory=${NAME}
TasksMax=infinity
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,7 @@
#!/bin/sh
findmnt /var/lib/containers/storage > /dev/null || mount --rbind --make-shared /var/lib/containers/storage /var/lib/containers/storage
findmnt /var/lib/origin > /dev/null || mount --bind --make-shared /var/lib/origin /var/lib/origin
findmnt /var/lib/kubelet > /dev/null || mount --bind --make-shared /var/lib/kubelet /var/lib/kubelet
mount --make-shared /run
findmnt /run/systemd > /dev/null || mount --bind --make-rslave /run/systemd /run/systemd

View File

@ -0,0 +1,5 @@
d ${RUN_DIRECTORY}/crio - - - - -
d /etc/crio - - - - -
Z /etc/crio - - - - -
d ${STATE_DIRECTORY}/origin - - - - -
d ${STATE_DIRECTORY}/kubelet - - - - -

View File

@ -4,13 +4,23 @@
git:
repo: "https://github.com/kubernetes-incubator/cri-tools.git"
dest: "{{ ansible_env.GOPATH }}/src/github.com/kubernetes-incubator/cri-tools"
version: "b42fc3f364dd48f649d55926c34492beeb9b2e99"
version: "{{ cri_tools_git_version }}"
force: "{{ force_clone | default(False) | bool}}"
- name: install crictl
command: "/usr/bin/go install github.com/kubernetes-incubator/cri-tools/cmd/crictl"
- name: install critest
command: "/usr/bin/go install github.com/kubernetes-incubator/cri-tools/cmd/critest"
- name: link crictl
file:
src: "{{ ansible_env.GOPATH }}/bin/crictl"
dest: /usr/bin/crictl
state: link
- name: link critest
file:
src: "{{ ansible_env.GOPATH }}/bin/critest"
dest: /usr/bin/critest
state: link

View File

@ -2,9 +2,10 @@
- name: clone kubernetes source repo
git:
repo: "https://github.com/runcom/kubernetes.git"
repo: "https://github.com/{{ k8s_github_fork }}/kubernetes.git"
dest: "{{ ansible_env.GOPATH }}/src/k8s.io/kubernetes"
version: "cri-o-patched-1.8"
# based on kube v1.9.0-alpha.2, update as needed
version: "{{ k8s_git_version }}"
force: "{{ force_clone | default(False) | bool}}"
- name: install etcd
@ -39,13 +40,15 @@
export PATH=/usr/local/go/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/root/bin:{{ ansible_env.GOPATH }}/bin:{{ ansible_env.GOPATH }}/src/k8s.io/kubernetes/third_party/etcd:{{ ansible_env.GOPATH }}/src/k8s.io/kubernetes/_output/local/bin/linux/amd64/
export CONTAINER_RUNTIME=remote
export CGROUP_DRIVER=systemd
export CONTAINER_RUNTIME_ENDPOINT='/var/run/crio.sock --runtime-request-timeout=5m'
export CONTAINER_RUNTIME_ENDPOINT='{{ crio_socket }} --runtime-request-timeout=5m'
export ALLOW_SECURITY_CONTEXT=","
export ALLOW_PRIVILEGED=1
export DNS_SERVER_IP={{ ansible_eth0.ipv4.address }}
export API_HOST={{ ansible_eth0.ipv4.address }}
export API_HOST_IP={{ ansible_eth0.ipv4.address }}
export DNS_SERVER_IP={{ ansible_default_ipv4.address }}
export API_HOST={{ ansible_default_ipv4.address }}
export API_HOST_IP={{ ansible_default_ipv4.address }}
export KUBE_ENABLE_CLUSTER_DNS=true
export ENABLE_HOSTPATH_PROVISIONER=true
export KUBE_ENABLE_CLUSTER_DASHBOARD=true
./hack/local-up-cluster.sh
mode: "u=rwx,g=rwx,o=x"

View File

@ -4,7 +4,7 @@
git:
repo: "https://github.com/opencontainers/runc.git"
dest: "{{ ansible_env.GOPATH }}/src/github.com/opencontainers/runc"
version: "84a082bfef6f932de921437815355186db37aeb1"
version: "c6e4a1ebeb1a72b529c6f1b6ee2b1ae5b868b14f"
- name: build runc
make:

View File

@ -0,0 +1,45 @@
---
- name: enable and start CRI-O
systemd:
name: crio
state: started
enabled: yes
daemon_reload: yes
- name: Flush the iptables
command: iptables -F
- name: Enable localnet routing
command: sysctl -w net.ipv4.conf.all.route_localnet=1
- name: Add masquerade for localhost
command: iptables -t nat -I POSTROUTING -s 127.0.0.1 ! -d 127.0.0.1 -j MASQUERADE
- name: run critest validation
shell: "critest -c --runtime-endpoint /var/run/crio/crio.sock --image-endpoint /var/run/crio/crio.sock v"
args:
chdir: "{{ ansible_env.GOPATH }}/src/github.com/kubernetes-incubator/cri-o"
async: 5400
poll: 30
when: ansible_distribution not in ['RedHat', 'CentOS']
# XXX: RHEL has an additional test which fails because of selinux but disabling
# it doesn't solve the issue.
# TODO(runcom): enable skipped tests once we fix them (selinux)
# https://bugzilla.redhat.com/show_bug.cgi?id=1414236
# https://access.redhat.com/solutions/2897781
- name: run critest validation
shell: "critest -c --runtime-endpoint /var/run/crio/crio.sock --image-endpoint /var/run/crio/crio.sock -s 'should not allow privilege escalation when true' v"
args:
chdir: "{{ ansible_env.GOPATH }}/src/github.com/kubernetes-incubator/cri-o"
async: 5400
poll: 30
when: ansible_distribution in ['RedHat', 'CentOS']
- name: run critest benchmarks
shell: "critest -c --runtime-endpoint /var/run/crio/crio.sock --image-endpoint /var/run/crio/crio.sock b"
args:
chdir: "{{ ansible_env.GOPATH }}/src/github.com/kubernetes-incubator/cri-o"
async: 5400
poll: 30

View File

@ -10,7 +10,7 @@
- name: update the server address for the custom cluster
lineinfile:
dest: /usr/local/bin/createcluster.sh
line: "export {{ item }}={{ ansible_eth0.ipv4.address }}"
line: "export {{ item }}={{ ansible_default_ipv4.address }}"
regexp: "^export {{ item }}="
state: present
with_items:
@ -37,13 +37,14 @@
path: "{{ artifacts }}"
state: directory
# TODO remove the last test skipped once https://github.com/kubernetes-incubator/cri-o/pull/1217 is merged
- name: Buffer the e2e testing command to workaround Ansible YAML folding "feature"
set_fact:
e2e_shell_cmd: >
/usr/bin/go run hack/e2e.go
--test
--test_args="-host=https://{{ ansible_default_ipv4.address }}:6443
--ginkgo.focus=\[Conformance\]
--ginkgo.skip=\[Slow\]|\[Serial\]|\[Disruptive\]|\[Flaky\]|\[Feature:.+\]|PersistentVolumes|\[HPA\]|should.support.building.a.client.with.a.CSR|should.support.inline.execution.and.attach
--report-dir={{ artifacts }}"
&> {{ artifacts }}/e2e.log
# Fix vim syntax hilighting: "

View File

@ -1,9 +1,14 @@
---
- name: ensure Golang dir is empty first
file:
path: /usr/local/go
state: absent
- name: fetch Golang
unarchive:
remote_src: yes
src: https://storage.googleapis.com/golang/go1.8.4.linux-amd64.tar.gz
src: "https://storage.googleapis.com/golang/go{{ version }}.linux-amd64.tar.gz"
dest: /usr/local
- name: link go toolchain
@ -47,5 +52,4 @@
- onsi/gomega
- cloudflare/cfssl/cmd/...
- jteeuwen/go-bindata/go-bindata
- vbatts/git-validation
- cpuguy83/go-md2man

View File

@ -10,15 +10,23 @@
- name: install Golang tools
include: golang.yml
vars:
version: "1.8.5"
- name: clone build and install bats
include: "build/bats.yml"
- name: clone build and install cri-tools
include: "build/cri-tools.yml"
vars:
cri_tools_git_version: "b42fc3f364dd48f649d55926c34492beeb9b2e99"
- name: clone build and install kubernetes
include: "build/kubernetes.yml"
vars:
k8s_git_version: "cri-o-node-e2e-patched-logs"
k8s_github_fork: "runcom"
crio_socket: "/var/run/crio.sock"
- name: clone build and install runc
include: "build/runc.yml"
@ -33,6 +41,8 @@
tags:
- integration
- e2e
- node-e2e
- critest
tasks:
- name: clone build and install cri-o
include: "build/cri-o.yml"
@ -44,6 +54,11 @@
tags:
- integration
tasks:
- name: clone build and install cri-tools
include: "build/cri-tools.yml"
vars:
force_clone: True
cri_tools_git_version: "a9e38a4a000bc1a4052fb33de1c967b8cfe9ad40"
- name: run cri-o integration tests
include: test.yml
@ -52,12 +67,59 @@
vars_files:
- "{{ playbook_dir }}/vars.yml"
tags:
- e2e
- critest
tasks:
- name: install Golang tools
include: golang.yml
vars:
version: "1.9.2"
- name: setup critest
include: "build/cri-tools.yml"
vars:
force_clone: True
cri_tools_git_version: "a9e38a4a000bc1a4052fb33de1c967b8cfe9ad40"
- name: run critest validation and benchmarks
include: critest.yml
- hosts: all
remote_user: root
vars_files:
- "{{ playbook_dir }}/vars.yml"
tags:
- node-e2e
tasks:
- name: install Golang tools
include: golang.yml
vars:
version: "1.9.2"
- name: clone build and install kubernetes
include: "build/kubernetes.yml"
vars:
force_clone: True
k8s_git_version: "master"
k8s_github_fork: "kubernetes"
crio_socket: "/var/run/crio/crio.sock"
- name: run k8s node-e2e tests
include: node-e2e.yml
- hosts: all
remote_user: root
vars_files:
- "{{ playbook_dir }}/vars.yml"
tags:
- e2e
tasks:
- name: install Golang tools
include: golang.yml
vars:
version: "1.9.2"
- name: clone build and install kubernetes
include: "build/kubernetes.yml"
vars:
force_clone: True
# master as of 12/11/2017
k8s_git_version: "master-nfs-fix"
k8s_github_fork: "runcom"
crio_socket: "/var/run/crio/crio.sock"
- name: run k8s e2e tests
include: e2e.yml

View File

@ -0,0 +1,26 @@
---
- name: enable and start CRI-O
systemd:
name: crio
state: started
enabled: yes
daemon_reload: yes
- name: disable SELinux
command: setenforce 0
- name: Flush the iptables
command: iptables -F
- name: run node-e2e tests
shell: |
# parametrize crio socket
# cgroup-driver???
# TODO(runcom): remove conformance focus, we want everything for testgrid
make test-e2e-node PARALLELISM=1 RUNTIME=remote CONTAINER_RUNTIME_ENDPOINT=/var/run/crio.sock IMAGE_SERVICE_ENDPOINT=/var/run/crio/crio.sock TEST_ARGS='--prepull-images=true --kubelet-flags="--cgroup-driver=systemd"' FOCUS="\[Conformance\]" &> {{ artifacts }}/node-e2e.log
args:
chdir: "{{ ansible_env.GOPATH }}/src/k8s.io/kubernetes"
async: 7200
poll: 10
ignore_errors: true

View File

@ -5,6 +5,7 @@
name: "{{ item }}"
state: present
with_items:
- atomic-registries
- container-selinux
- curl
- device-mapper-devel
@ -41,9 +42,9 @@
- ostree-devel
- pkgconfig
- python
- python2-boto
- python2-crypto
- python-devel
- python-rhsm-certificates
- python-virtualenv
- PyYAML
- redhat-rpm-config
@ -57,6 +58,22 @@
async: 600
poll: 10
- name: Add python2-boto for Fedora
package:
name: "{{ item }}"
state: present
with_items:
- python2-boto
when: ansible_distribution in ['Fedora']
- name: Add python-boto for RHEL and CentOS
package:
name: "{{ item }}"
state: present
with_items:
- python-boto
when: ansible_distribution in ['RedHat', 'CentOS']
- name: Add Btrfs for Fedora
package:
name: "{{ item }}"

View File

@ -1,8 +1,5 @@
---
- name: clone build and install cri-tools
include: "build/cri-tools.yml"
- name: Make testing output verbose so it can be converted to xunit
lineinfile:
dest: "{{ ansible_env.GOPATH }}/src/k8s.io/kubernetes/hack/make-rules/test.sh"

View File

@ -1 +1 @@
runtime-endpoint: /var/run/crio.sock
runtime-endpoint: /var/run/crio/crio.sock

View File

@ -5,157 +5,122 @@
crio - OCI Kubernetes Container Runtime daemon
# SYNOPSIS
**crio**
[**--apparmor-profile**=[*value*]]
[**--cgroup-manager**=[*value*]]
[**--cni-config-dir**=[*value*]]
[**--cni-plugin-dir**=[*value*]]
[**--config**=[*value*]]
[**--conmon**=[*value*]]
[**--cpu-profile**=[*value*]]
[**--default-transport**=[*value*]]
[**--help**|**-h**]
[**--insecure-registry**=[*value*]]
[**--listen**=[*value*]]
[**--log**=[*value*]]
[**--log-format value**]
[**--log-level value**]
[**--pause-command**=[*value*]]
[**--pause-image**=[*value*]]
[**--registry**=[*value*]]
[**--root**=[*value*]]
[**--runroot**=[*value*]]
[**--runtime**=[*value*]]
[**--seccomp-profile**=[*value*]]
[**--selinux**]
[**--signature-policy**=[*value*]]
[**--storage-driver**=[*value*]]
[**--storage-opt**=[*value*]]
[**--version**|**-v**]
crio
```
[--apparmor-profile=[value]]
[--cgroup-manager=[value]]
[--cni-config-dir=[value]]
[--cni-plugin-dir=[value]]
[--config=[value]]
[--conmon=[value]]
[--cpu-profile=[value]]
[--default-transport=[value]]
[--help|-h]
[--insecure-registry=[value]]
[--listen=[value]]
[--log=[value]]
[--log-format value]
[--log-level value]
[--pause-command=[value]]
[--pause-image=[value]]
[--registry=[value]]
[--root=[value]]
[--runroot=[value]]
[--runtime=[value]]
[--seccomp-profile=[value]]
[--selinux]
[--signature-policy=[value]]
[--storage-driver=[value]]
[--storage-opt=[value]]
[--version|-v]
```
# DESCRIPTION
OCI-based implementation of Kubernetes Container Runtime Interface Daemon
crio is meant to provide an integration path between OCI conformant runtimes and the kubelet. Specifically, it implements the Kubelet Container Runtime Interface (CRI) using OCI conformant runtimes. The scope of crio is tied to the scope of the CRI.
* Support multiple image formats including the existing Docker image format
* Support for multiple means to download images including trust & image verification
* Container image management (managing image layers, overlay filesystems, etc)
* Container process lifecycle management
* Monitoring and logging required to satisfy the CRI
* Resource isolation as required by the CRI
**crio [GLOBAL OPTIONS]**
**crio [GLOBAL OPTIONS] config [OPTIONS]**
1. Support multiple image formats including the existing Docker image format.
2. Support for multiple means to download images including trust & image verification.
3. Container image management (managing image layers, overlay filesystems, etc).
4. Container process lifecycle management.
5. Monitoring and logging required to satisfy the CRI.
6. Resource isolation as required by the CRI.
**Usage**:
```
crio [GLOBAL OPTIONS]
crio [GLOBAL OPTIONS] config [OPTIONS]
```
# GLOBAL OPTIONS
**--apparmor_profile**="": Name of the apparmor profile to be used as the runtime's default (default: "crio-default")
**--apparmor_profile**=""
Name of the apparmor profile to be used as the runtime's default (default: "crio-default")
**--cgroup-manager**="": cgroup manager (cgroupfs or systemd)
**--cgroup-manager**=""
cgroup manager (cgroupfs or systemd)
**--config**="": path to configuration file
**--config**=""
path to configuration file
**--conmon**="": path to the conmon executable (default: "/usr/local/libexec/crio/conmon")
**--conmon**=""
path to the conmon executable (default: "/usr/local/libexec/crio/conmon")
**--cpu-profile**="": set the CPU profile file path
**--cpu-profile**=""
set the CPU profile file path
**--default-transport**: A prefix to prepend to image names that can't be pulled as-is.
**--default-transport**
A prefix to prepend to image names that can't be pulled as-is.
**--help, -h**: Print usage statement
**--help, -h**
Print usage statement
**--insecure-registry=**: Enable insecure registry communication, i.e., enable un-encrypted and/or untrusted communication.
**--insecure-registry=**
Enable insecure registry communication, i.e., enable un-encrypted
and/or untrusted communication.
1. List of insecure registries can contain an element with CIDR notation to specify a whole subnet.
2. Insecure registries accept HTTP or accept HTTPS with certificates from unknown CAs.
3. Enabling `--insecure-registry` is useful when running a local registry. However, because its use creates security vulnerabilities, **it should ONLY be enabled for testing purposes**. For increased security, users should add their CA to their system's list of trusted CAs instead of using `--insecure-registry`.
List of insecure registries can contain an element with CIDR notation
to specify a whole subnet. Insecure registries accept HTTP and/or
accept HTTPS with certificates from unknown CAs.
**--image-volumes**="": Image volume handling ('mkdir', 'bind' or 'ignore') (default: "mkdir")
Enabling --insecure-registry is useful when running a local registry.
However, because its use creates security vulnerabilities it should
ONLY be enabled for testing purposes. For increased security, users
should add their CA to their system's list of trusted CAs instead of
using --insecure-registry.
1. mkdir: A directory is created inside the container root filesystem for the volumes.
2. bind: A directory is created inside container state directory and bind mounted into the container for the volumes.
3. ignore: All volumes are just ignored and no action is taken.
**--image-volumes**=""
Image volume handling ('mkdir', 'bind' or 'ignore') (default: "mkdir")
mkdir: A directory is created inside the container root filesystem for the volumes.
bind: A directory is created inside container state directory and bind mounted into
the container for the volumes.
ignore: All volumes are just ignored and no action is taken.
**--listen**="": Path to CRI-O socket (default: "/var/run/crio/crio.sock")
**--listen**=""
Path to CRI-O socket (default: "/var/run/crio.sock")
**--log**="": Set the log file path where internal debug information is written
**--log**=""
Set the log file path where internal debug information is written
**--log-format**="": Set the format used by logs ('text' (default), or 'json') (default: "text")
**--log-format**=""
Set the format used by logs ('text' (default), or 'json') (default: "text")
**--log-level**="": log crio messages above specified level: debug, info (default), warn, error, fatal or panic
**--log-level**=""
log crio messages above specified level: debug, info (default), warn, error, fatal or panic
**--log-size-max**="": Maximum log size in bytes for a container (default: -1 (no limit)). If it is positive, it must be >= 8192 (to match/exceed conmon read buffer).
**--log-size-max**=""
Maximum log size in bytes for a container (default: -1 (no limit)).
If it is positive, it must be >= 8192 (to match/exceed conmon read buffer).
**--pause-command**="": Path to the pause executable in the pause image (default: "/pause")
**--pause-command**=""
Path to the pause executable in the pause image (default: "/pause")
**--pause-image**="": Image which contains the pause executable (default: "kubernetes/pause")
**--pause-image**=""
Image which contains the pause executable (default: "kubernetes/pause")
**--pids-limit**="": Maximum number of processes allowed in a container (default: 1024)
**--pids-limit**=""
Maximum number of processes allowed in a container (default: 1024)
**--enable-shared-pid-namespace**="": Enable using a shared PID namespace for containers in a pod (default: false)
**--root**=""
The crio root dir (default: "/var/lib/containers/storage")
**--root**="": The crio root dir (default: "/var/lib/containers/storage")
**--registry**=""
Registry host which will be prepended to unqualified images, can be specified multiple times
**--registry**="": Registry host which will be prepended to unqualified images, can be specified multiple times
**--runroot**=""
The crio state dir (default: "/var/run/containers/storage")
**--runroot**="": The crio state dir (default: "/var/run/containers/storage")
**--runtime**=""
OCI runtime path (default: "/usr/bin/runc")
**--runtime**="": OCI runtime path (default: "/usr/bin/runc")
**--selinux**=*true*|*false*
Enable selinux support (default: false)
**--selinux**=**true**|**false**: Enable selinux support (default: false)
**--seccomp-profile**=""
Path to the seccomp json profile to be used as the runtime's default (default: "/etc/crio/seccomp.json")
**--seccomp-profile**="": Path to the seccomp json profile to be used as the runtime's default (default: "/etc/crio/seccomp.json")
**--signature-policy**=""
Path to the signature policy json file (default: "", to use the system-wide default)
**--signature-policy**="": Path to the signature policy json file (default: "", to use the system-wide default)
**--storage-driver**
OCI storage driver (default: "devicemapper")
**--storage-driver**: OCI storage driver (default: "devicemapper")
**--storage-opt**
OCI storage driver option (no default)
**--storage-opt**: OCI storage driver option (no default)
**--cni-config-dir**=""
CNI configuration files directory (default: "/etc/cni/net.d/")
**--cni-config-dir**="": CNI configuration files directory (default: "/etc/cni/net.d/")
**--cni-plugin-dir**=""
CNI plugin binaries directory (default: "/opt/cni/bin/")
**--cni-plugin-dir**="": CNI plugin binaries directory (default: "/opt/cni/bin/")
**--cpu-profile**
Set the CPU profile file path
**--cpu-profile**: Set the CPU profile file path
**--version, -v**
Print the version
**--version, -v**: Print the version
# COMMANDS
CRI-O's default command is to start the daemon. However, it currently offers a

View File

@ -68,7 +68,7 @@ Example:
## CRIO.API TABLE
**listen**=""
Path to crio socket (default: "/var/run/crio.sock")
Path to crio socket (default: "/var/run/crio/crio.sock")
## CRIO.RUNTIME TABLE
@ -87,6 +87,9 @@ Example:
**pids_limit**=""
Maximum number of processes allowed in a container (default: 1024)
**enable_shared_pid_namespace**=""
Enable using a shared PID namespace for containers in a pod (default: false)
**runtime**=""
OCI runtime path (default: "/usr/bin/runc")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

7
hack/libdm_installed.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
cc -E - > /dev/null 2> /dev/null << EOF
#include <libdevmapper.h>
EOF
if test $? -ne 0 ; then
echo exclude_graphdriver_devicemapper
fi

30
hack/validate/.validate Normal file
View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -e -o pipefail
if [ -z "$VALIDATE_UPSTREAM" ]; then
# this is kind of an expensive check, so let's not do this twice if we
# are running more than one validate bundlescript
VALIDATE_REPO='https://github.com/kubernetes-incubator/cri-o.git'
VALIDATE_BRANCH='master'
VALIDATE_HEAD="$(git rev-parse --verify HEAD)"
git fetch -q "$VALIDATE_REPO" "refs/heads/$VALIDATE_BRANCH"
VALIDATE_UPSTREAM="$(git rev-parse --verify FETCH_HEAD)"
VALIDATE_COMMIT_LOG="$VALIDATE_UPSTREAM..$VALIDATE_HEAD"
VALIDATE_COMMIT_DIFF="$VALIDATE_UPSTREAM...$VALIDATE_HEAD"
validate_diff() {
if [ "$VALIDATE_UPSTREAM" != "$VALIDATE_HEAD" ]; then
git diff "$VALIDATE_COMMIT_DIFF" "$@"
fi
}
validate_log() {
if [ "$VALIDATE_UPSTREAM" != "$VALIDATE_HEAD" ]; then
git log "$VALIDATE_COMMIT_LOG" "$@"
fi
}
fi

View File

@ -1,21 +0,0 @@
#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
find_files() {
find . -not \( \
\( \
-wholename '*/vendor/*' \
\) -prune \
\) -name '*.go'
}
GOFMT="gofmt -s"
bad_files=$(find_files | xargs $GOFMT -l)
if [[ -n "${bad_files}" ]]; then
echo "!!! '$GOFMT' needs to be run on the following files: "
echo "${bad_files}"
exit 1
fi

View File

@ -53,6 +53,7 @@ type HookParams struct {
Cmds []string `json:"cmds"`
Annotations []string `json:"annotations"`
HasBindMounts bool `json:"hasbindmounts"`
Arguments []string `json:"arguments"`
}
```
@ -63,6 +64,7 @@ type HookParams struct {
| cmds | List of regular expressions to match the command for running the container. If the command matches a regex, the hook will be run | Optional |
| annotations | List of regular expressions to match against the Annotations in the container runtime spec, if an Annotation matches the hook will be run|optional |
| hasbindmounts | Tells CRI-O to run the hook if the container has bind mounts from the host into the container | Optional |
| arguments | Additional arguments to append to the hook command when executing it. For example --debug | Optional |
### Example
@ -85,6 +87,7 @@ cat /etc/containers/oci/hooks.d/oci-systemd-hook.json
"hasbindmounts": true,
"hook": "/usr/libexec/oci/hooks.d/oci-umount",
"stages": [ "prestart" ]
"arguments": [ "--debug" ]
}
```
In this example the oci-umount will only be run during the prestart phase if the container has volume/bind mounts from the host into the container.
In this example the oci-umount will only be run during the prestart phase if the container has volume/bind mounts from the host into the container, it will also execute oci-umount with the --debug argument.

View File

@ -13,17 +13,15 @@ Below, you can find an instruction how to switch one or more nodes on running ku
### Preparing crio
You must prepare and install `crio` on each node you would like to switch. Here's the list of files that must be provided:
You must prepare and install `crio` on each node you would like to switch.
Besides the files installed by `make install install.config`, here's the list of files that must be provided:
| File path | Description | Location |
|--------------------------------------------|----------------------------|-----------------------------------------------------|
| `/etc/crio/crio.conf` | crio configuration | Generated on cri-o `make install` |
| `/etc/crio/seccomp.conf` | seccomp config | Example stored in cri-o repository |
| `/etc/containers/policy.json` | containers policy | Example stored in cri-o repository |
| `/bin/{crio, runc}` | `crio` and `runc` binaries | Built from cri-o repository |
| `/usr/local/libexec/crio/conmon` | `conmon` binary | Built from cri-o repository |
| `/opt/cni/bin/{flannel, bridge,...}` | CNI plugins binaries | Can be built from sources `containernetworking/cni` |
| `/etc/cni/net.d/10-mynet.conf` | Network config | Example stored in [README file](README.md) |
| File path | Description | Location |
|--------------------------------------------|-----------------------------|---------------------------------------------------------|
| `/etc/containers/policy.json` | containers policy | [Example](test/policy.json) stored in cri-o repository |
| `/bin/runc` | `runc` or other OCI runtime | Can be build from sources `opencontainers/runc` |
| `/opt/cni/bin/{flannel, bridge,...}` | CNI plugins binaries | Can be built from sources `containernetworking/plugins` |
| `/etc/cni/net.d/...` | CNI network config | Example [here](contrib/cni) |
`crio` binary can be executed directly on host, inside the container or in any way.
However, recommended way is to set it as a systemd service.
@ -79,7 +77,7 @@ KUBELET_ARGS="--pod-manifest-path=/etc/kubernetes/manifests
You need to add following parameters to `KUBELET_ARGS`:
* `--experimental-cri=true` - Use Container Runtime Interface. Will be true by default from kubernetes 1.6 release.
* `--container-runtime=remote` - Use remote runtime with provided socket.
* `--container-runtime-endpoint=/var/run/crio.sock` - Socket for remote runtime (default `crio` socket localization).
* `--container-runtime-endpoint=/var/run/crio/crio.sock` - Socket for remote runtime (default `crio` socket localization).
* `--runtime-request-timeout=10m` - Optional but useful. Some requests, especially pulling huge images, may take longer than default (2 minutes) and will cause an error.
Kubelet is prepared now.

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"bytes"
@ -83,7 +83,7 @@ type RootConfig struct {
LogDir string `toml:"log_dir"`
// FileLocking specifies whether to use file-based or in-memory locking
// File-based locking is required when multiple users of libkpod are
// File-based locking is required when multiple users of lib are
// present on the same system
FileLocking bool `toml:"file_locking"`
}
@ -121,6 +121,9 @@ type RuntimeConfig struct {
// NoPivot instructs the runtime to not use `pivot_root`, but instead use `MS_MOVE`
NoPivot bool `toml:"no_pivot"`
// EnableSharePidNamespace instructs the runtime to enable share pid namespace
EnableSharedPIDNamespace bool `toml:"enable_shared_pid_namespace"`
// Conmon is the path to conmon binary, used for managing the runtime.
Conmon string `toml:"conmon"`

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"io/ioutil"

View File

@ -1,10 +1,10 @@
package libkpod
package lib
import (
"fmt"
cstorage "github.com/containers/storage"
"github.com/kubernetes-incubator/cri-o/libkpod/sandbox"
"github.com/kubernetes-incubator/cri-o/lib/sandbox"
"github.com/kubernetes-incubator/cri-o/oci"
"github.com/kubernetes-incubator/cri-o/pkg/registrar"
"github.com/pkg/errors"

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"encoding/json"
@ -12,7 +12,7 @@ import (
cstorage "github.com/containers/storage"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/truncindex"
"github.com/kubernetes-incubator/cri-o/libkpod/sandbox"
"github.com/kubernetes-incubator/cri-o/lib/sandbox"
"github.com/kubernetes-incubator/cri-o/oci"
"github.com/kubernetes-incubator/cri-o/pkg/annotations"
"github.com/kubernetes-incubator/cri-o/pkg/registrar"
@ -168,7 +168,7 @@ func New(config *Config) (*ContainerServer, error) {
state: &containerServerState{
containers: oci.NewMemoryStore(),
infraContainers: oci.NewMemoryStore(),
sandboxes: make(map[string]*sandbox.Sandbox),
sandboxes: sandbox.NewMemoryStore(),
processLevels: make(map[string]int),
},
config: config,
@ -617,70 +617,53 @@ func (c *ContainerServer) Shutdown() error {
type containerServerState struct {
containers oci.ContainerStorer
infraContainers oci.ContainerStorer
sandboxes map[string]*sandbox.Sandbox
sandboxes sandbox.Storer
// processLevels The number of sandboxes using the same SELinux MCS level. Need to release MCS Level, when count reaches 0
processLevels map[string]int
}
// AddContainer adds a container to the container state store
func (c *ContainerServer) AddContainer(ctr *oci.Container) {
c.stateLock.Lock()
defer c.stateLock.Unlock()
sandbox := c.state.sandboxes[ctr.Sandbox()]
sandbox := c.state.sandboxes.Get(ctr.Sandbox())
sandbox.AddContainer(ctr)
c.state.containers.Add(ctr.ID(), ctr)
}
// AddInfraContainer adds a container to the container state store
func (c *ContainerServer) AddInfraContainer(ctr *oci.Container) {
c.stateLock.Lock()
defer c.stateLock.Unlock()
c.state.infraContainers.Add(ctr.ID(), ctr)
}
// GetContainer returns a container by its ID
func (c *ContainerServer) GetContainer(id string) *oci.Container {
c.stateLock.Lock()
defer c.stateLock.Unlock()
return c.state.containers.Get(id)
}
// GetInfraContainer returns a container by its ID
func (c *ContainerServer) GetInfraContainer(id string) *oci.Container {
c.stateLock.Lock()
defer c.stateLock.Unlock()
return c.state.infraContainers.Get(id)
}
// HasContainer checks if a container exists in the state
func (c *ContainerServer) HasContainer(id string) bool {
c.stateLock.Lock()
defer c.stateLock.Unlock()
ctr := c.state.containers.Get(id)
return ctr != nil
return c.state.containers.Get(id) != nil
}
// RemoveContainer removes a container from the container state store
func (c *ContainerServer) RemoveContainer(ctr *oci.Container) {
c.stateLock.Lock()
defer c.stateLock.Unlock()
sbID := ctr.Sandbox()
sb := c.state.sandboxes[sbID]
sb := c.state.sandboxes.Get(sbID)
sb.RemoveContainer(ctr)
c.state.containers.Delete(ctr.ID())
}
// RemoveInfraContainer removes a container from the container state store
func (c *ContainerServer) RemoveInfraContainer(ctr *oci.Container) {
c.stateLock.Lock()
defer c.stateLock.Unlock()
c.state.infraContainers.Delete(ctr.ID())
}
// listContainers returns a list of all containers stored by the server state
func (c *ContainerServer) listContainers() []*oci.Container {
c.stateLock.Lock()
defer c.stateLock.Unlock()
return c.state.containers.List()
}
@ -704,62 +687,52 @@ func (c *ContainerServer) ListContainers(filters ...func(*oci.Container) bool) (
// AddSandbox adds a sandbox to the sandbox state store
func (c *ContainerServer) AddSandbox(sb *sandbox.Sandbox) {
c.state.sandboxes.Add(sb.ID(), sb)
c.stateLock.Lock()
defer c.stateLock.Unlock()
c.state.sandboxes[sb.ID()] = sb
c.state.processLevels[selinux.NewContext(sb.ProcessLabel())["level"]]++
c.stateLock.Unlock()
}
// GetSandbox returns a sandbox by its ID
func (c *ContainerServer) GetSandbox(id string) *sandbox.Sandbox {
c.stateLock.Lock()
defer c.stateLock.Unlock()
return c.state.sandboxes[id]
return c.state.sandboxes.Get(id)
}
// GetSandboxContainer returns a sandbox's infra container
func (c *ContainerServer) GetSandboxContainer(id string) *oci.Container {
c.stateLock.Lock()
defer c.stateLock.Unlock()
sb, ok := c.state.sandboxes[id]
if !ok {
return nil
}
sb := c.state.sandboxes.Get(id)
return sb.InfraContainer()
}
// HasSandbox checks if a sandbox exists in the state
func (c *ContainerServer) HasSandbox(id string) bool {
c.stateLock.Lock()
defer c.stateLock.Unlock()
_, ok := c.state.sandboxes[id]
return ok
return c.state.sandboxes.Get(id) != nil
}
// RemoveSandbox removes a sandbox from the state store
func (c *ContainerServer) RemoveSandbox(id string) {
c.stateLock.Lock()
defer c.stateLock.Unlock()
processLabel := c.state.sandboxes[id].ProcessLabel()
delete(c.state.sandboxes, id)
sb := c.state.sandboxes.Get(id)
processLabel := sb.ProcessLabel()
level := selinux.NewContext(processLabel)["level"]
c.state.processLevels[level]--
if c.state.processLevels[level] == 0 {
label.ReleaseLabel(processLabel)
delete(c.state.processLevels, level)
c.stateLock.Lock()
pl, ok := c.state.processLevels[level]
if ok {
c.state.processLevels[level] = pl - 1
if c.state.processLevels[level] == 0 {
label.ReleaseLabel(processLabel)
delete(c.state.processLevels, level)
}
}
c.stateLock.Unlock()
c.state.sandboxes.Delete(id)
}
// ListSandboxes lists all sandboxes in the state store
func (c *ContainerServer) ListSandboxes() []*sandbox.Sandbox {
c.stateLock.Lock()
defer c.stateLock.Unlock()
sbArray := make([]*sandbox.Sandbox, 0, len(c.state.sandboxes))
for _, sb := range c.state.sandboxes {
sbArray = append(sbArray, sb)
}
return sbArray
return c.state.sandboxes.List()
}
// LibcontainerStats gets the stats for the container with the given id from runc/libcontainer

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"encoding/json"
@ -27,6 +27,7 @@ type HookParams struct {
Cmds []string `json:"cmd"`
Annotations []string `json:"annotation"`
HasBindMounts bool `json:"hasbindmounts"`
Arguments []string `json:"arguments"`
}
// readHook reads hooks json files, verifies it and returns the json config

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"github.com/docker/docker/pkg/signal"

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"path"

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"github.com/kubernetes-incubator/cri-o/oci"

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"os"

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"encoding/json"

31
lib/sandbox/history.go Normal file
View File

@ -0,0 +1,31 @@
package sandbox
import "sort"
// History is a convenience type for storing a list of sandboxes,
// sorted by creation date in descendant order.
type History []*Sandbox
// Len returns the number of sandboxes in the history.
func (history *History) Len() int {
return len(*history)
}
// Less compares two sandboxes and returns true if the second one
// was created before the first one.
func (history *History) Less(i, j int) bool {
sandboxes := *history
// FIXME: state access should be serialized
return sandboxes[j].created.Before(sandboxes[i].created)
}
// Swap switches sandboxes i and j positions in the history.
func (history *History) Swap(i, j int) {
sandboxes := *history
sandboxes[i], sandboxes[j] = sandboxes[j], sandboxes[i]
}
// sort orders the history by creation date in descendant order.
func (history *History) sort() {
sort.Sort(history)
}

View File

@ -0,0 +1,93 @@
package sandbox
import "sync"
// memoryStore implements a Store in memory.
type memoryStore struct {
s map[string]*Sandbox
sync.RWMutex
}
// NewMemoryStore initializes a new memory store.
func NewMemoryStore() Storer {
return &memoryStore{
s: make(map[string]*Sandbox),
}
}
// Add appends a new sandbox to the memory store.
// It overrides the id if it existed before.
func (c *memoryStore) Add(id string, cont *Sandbox) {
c.Lock()
c.s[id] = cont
c.Unlock()
}
// Get returns a sandbox from the store by id.
func (c *memoryStore) Get(id string) *Sandbox {
var res *Sandbox
c.RLock()
res = c.s[id]
c.RUnlock()
return res
}
// Delete removes a sandbox from the store by id.
func (c *memoryStore) Delete(id string) {
c.Lock()
delete(c.s, id)
c.Unlock()
}
// List returns a sorted list of sandboxes from the store.
// The sandboxes are ordered by creation date.
func (c *memoryStore) List() []*Sandbox {
sandboxes := History(c.all())
sandboxes.sort()
return sandboxes
}
// Size returns the number of sandboxes in the store.
func (c *memoryStore) Size() int {
c.RLock()
defer c.RUnlock()
return len(c.s)
}
// First returns the first sandbox found in the store by a given filter.
func (c *memoryStore) First(filter StoreFilter) *Sandbox {
for _, cont := range c.all() {
if filter(cont) {
return cont
}
}
return nil
}
// ApplyAll calls the reducer function with every sandbox in the store.
// This operation is asynchronous in the memory store.
// NOTE: Modifications to the store MUST NOT be done by the StoreReducer.
func (c *memoryStore) ApplyAll(apply StoreReducer) {
wg := new(sync.WaitGroup)
for _, cont := range c.all() {
wg.Add(1)
go func(sandbox *Sandbox) {
apply(sandbox)
wg.Done()
}(cont)
}
wg.Wait()
}
func (c *memoryStore) all() []*Sandbox {
c.RLock()
sandboxes := make([]*Sandbox, 0, len(c.s))
for _, cont := range c.s {
sandboxes = append(sandboxes, cont)
}
c.RUnlock()
return sandboxes
}
var _ Storer = &memoryStore{}

View File

@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
"sync"
"time"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/docker/docker/pkg/mount"
@ -158,6 +159,7 @@ type Sandbox struct {
// ipv4 or ipv6 cache
ip string
seccompProfilePath string
created time.Time
}
const (
@ -202,6 +204,7 @@ func New(id, namespace, name, kubeName, logDir string, labels, annotations map[s
sb.resolvPath = resolvPath
sb.hostname = hostname
sb.portMappings = portMappings
sb.created = time.Now()
return sb, nil
}

27
lib/sandbox/store.go Normal file
View File

@ -0,0 +1,27 @@
package sandbox
// StoreFilter defines a function to filter
// sandboxes in the store.
type StoreFilter func(*Sandbox) bool
// StoreReducer defines a function to
// manipulate sandboxes in the store
type StoreReducer func(*Sandbox)
// Storer defines an interface that any container store must implement.
type Storer interface {
// Add appends a new sandbox to the store.
Add(string, *Sandbox)
// Get returns a sandbox from the store by the identifier it was stored with.
Get(string) *Sandbox
// Delete removes a sandbox from the store by the identifier it was stored with.
Delete(string)
// List returns a list of sandboxes from the store.
List() []*Sandbox
// Size returns the number of sandboxes in the store.
Size() int
// First returns the first sandbox found in the store by a given filter.
First(StoreFilter) *Sandbox
// ApplyAll calls the reducer function with every sandbox in the store.
ApplyAll(StoreReducer)
}

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"path/filepath"

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"github.com/kubernetes-incubator/cri-o/oci"

View File

@ -1,4 +1,4 @@
package libkpod
package lib
import (
"github.com/kubernetes-incubator/cri-o/oci"

View File

@ -25,8 +25,9 @@ func (c *memoryStore) Add(id string, cont *Container) {
// Get returns a container from the store by id.
func (c *memoryStore) Get(id string) *Container {
var res *Container
c.RLock()
res := c.s[id]
res = c.s[id]
c.RUnlock()
return res
}

View File

@ -359,9 +359,9 @@ func parseLog(log []byte) (stdout, stderr []byte) {
continue
}
// The format of log lines is "DATE pipe REST".
parts := bytes.SplitN(line, []byte{' '}, 3)
if len(parts) < 3 {
// The format of log lines is "DATE pipe LogTag REST".
parts := bytes.SplitN(line, []byte{' '}, 4)
if len(parts) < 4 {
// Ignore the line if it's formatted incorrectly, but complain
// about it so it can be debugged.
logrus.Warnf("hit invalid log format: %q", string(line))
@ -369,7 +369,15 @@ func parseLog(log []byte) (stdout, stderr []byte) {
}
pipe := string(parts[1])
content := parts[2]
content := parts[3]
linetype := string(parts[2])
if linetype == "P" {
contentLen := len(content)
if content[contentLen-1] == '\n' {
content = content[:contentLen-1]
}
}
switch pipe {
case "stdout":
@ -415,15 +423,6 @@ func (r *Runtime) ExecSync(c *Container, command []string, timeout int64) (resp
os.RemoveAll(logPath)
}()
f, err := ioutil.TempFile("", "exec-process")
if err != nil {
return nil, ExecSyncError{
ExitCode: -1,
Err: err,
}
}
defer os.RemoveAll(f.Name())
var args []string
args = append(args, "-c", c.id)
args = append(args, "-r", r.Path(c))
@ -439,25 +438,16 @@ func (r *Runtime) ExecSync(c *Container, command []string, timeout int64) (resp
args = append(args, "-l", logPath)
args = append(args, "--socket-dir-path", ContainerAttachSocketDir)
pspec := c.Spec().Process
pspec.Env = append(pspec.Env, r.conmonEnv...)
pspec.Args = command
processJSON, err := json.Marshal(pspec)
processFile, err := PrepareProcessExec(c, command, false)
if err != nil {
return nil, ExecSyncError{
ExitCode: -1,
Err: err,
}
}
defer os.RemoveAll(processFile.Name())
if err := ioutil.WriteFile(f.Name(), processJSON, 0644); err != nil {
return nil, ExecSyncError{
ExitCode: -1,
Err: err,
}
}
args = append(args, "--exec-process-spec", f.Name())
args = append(args, "--exec-process-spec", processFile.Name())
cmd := exec.Command(r.conmonPath, args...)
@ -662,7 +652,7 @@ func (r *Runtime) SetStartFailed(c *Container, err error) {
func (r *Runtime) UpdateStatus(c *Container) error {
c.opLock.Lock()
defer c.opLock.Unlock()
out, err := exec.Command(r.Path(c), "state", c.id).CombinedOutput()
out, err := exec.Command(r.Path(c), "state", c.id).Output()
if err != nil {
// there are many code paths that could lead to have a bad state in the
// underlying runtime.
@ -765,3 +755,27 @@ func (r *Runtime) UnpauseContainer(c *Container) error {
_, err := utils.ExecCmd(r.Path(c), "resume", c.id)
return err
}
// PrepareProcessExec returns the path of the process.json used in runc exec -p
// caller is responsible to close the returned *os.File if needed.
func PrepareProcessExec(c *Container, cmd []string, tty bool) (*os.File, error) {
f, err := ioutil.TempFile("", "exec-process-")
if err != nil {
return nil, err
}
pspec := c.Spec().Process
pspec.Args = cmd
if tty {
pspec.Terminal = true
}
processJSON, err := json.Marshal(pspec)
if err != nil {
return nil, err
}
if err := ioutil.WriteFile(f.Name(), processJSON, 0644); err != nil {
return nil, err
}
return f, nil
}

View File

@ -2,33 +2,42 @@ package storage
import (
"errors"
"fmt"
"net"
"path/filepath"
"regexp"
"path"
"strings"
"github.com/containers/image/copy"
"github.com/containers/image/docker/reference"
"github.com/containers/image/image"
"github.com/containers/image/manifest"
"github.com/containers/image/signature"
istorage "github.com/containers/image/storage"
"github.com/containers/image/transports/alltransports"
"github.com/containers/image/types"
"github.com/containers/storage"
distreference "github.com/docker/distribution/reference"
digest "github.com/opencontainers/go-digest"
)
const (
minimumTruncatedIDLength = 3
)
var (
// ErrCannotParseImageID is returned when we try to ResolveNames for an image ID
ErrCannotParseImageID = errors.New("cannot parse an image ID")
// ErrImageMultiplyTagged is returned when we try to remove an image that still has multiple names
ErrImageMultiplyTagged = errors.New("image still has multiple names applied")
)
// ImageResult wraps a subset of information about an image: its ID, its names,
// and the size, if known, or nil if it isn't.
type ImageResult struct {
ID string
Names []string
Size *uint64
// TODO(runcom): this is an hack for https://github.com/kubernetes-incubator/cri-o/pull/1136
// drop this when we have proper image IDs (as in, image IDs should be just
// the config blog digest which is stable across same images).
ID string
Name string
RepoTags []string
RepoDigests []string
Size *uint64
Digest digest.Digest
ConfigDigest digest.Digest
}
@ -45,6 +54,11 @@ type imageService struct {
registries []string
}
// sizer knows its size.
type sizer interface {
Size() (int64, error)
}
// ImageServer wraps up various CRI-related activities into a reusable
// implementation.
type ImageServer interface {
@ -57,6 +71,9 @@ type ImageServer interface {
PrepareImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.Image, error)
// PullImage imports an image from the specified location.
PullImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.ImageReference, error)
// UntagImage removes a name from the specified image, and if it was
// the only name the image had, removes the image.
UntagImage(systemContext *types.SystemContext, imageName string) error
// RemoveImage deletes the specified image.
RemoveImage(systemContext *types.SystemContext, imageName string) error
// GetStore returns the reference to the storage library Store which
@ -86,6 +103,66 @@ func (svc *imageService) getRef(name string) (types.ImageReference, error) {
return ref, nil
}
func sortNamesByType(names []string) (bestName string, tags, digests []string) {
for _, name := range names {
if len(name) > 72 && name[len(name)-72:len(name)-64] == "@sha256:" {
digests = append(digests, name)
} else {
tags = append(tags, name)
}
}
if len(digests) > 0 {
bestName = digests[0]
}
if len(tags) > 0 {
bestName = tags[0]
}
return bestName, tags, digests
}
func (svc *imageService) makeRepoDigests(knownRepoDigests, tags []string, imageID string) (imageDigest digest.Digest, repoDigests []string) {
// Look up the image's digest.
img, err := svc.store.Image(imageID)
if err != nil {
return "", knownRepoDigests
}
imageDigest = img.Digest
if imageDigest == "" {
imgDigest, err := svc.store.ImageBigDataDigest(imageID, storage.ImageDigestBigDataKey)
if err != nil || imgDigest == "" {
return "", knownRepoDigests
}
imageDigest = imgDigest
}
// If there are no names to convert to canonical references, we're done.
if len(tags) == 0 {
return imageDigest, knownRepoDigests
}
// We only want to supplement what's already explicitly in the list, so keep track of values
// that we already know.
digestMap := make(map[string]struct{})
repoDigests = knownRepoDigests
for _, repoDigest := range knownRepoDigests {
digestMap[repoDigest] = struct{}{}
}
// For each tagged name, parse the name, and if we can extract a named reference, convert
// it into a canonical reference using the digest and add it to the list.
for _, tag := range tags {
if ref, err2 := reference.ParseAnyReference(tag); err2 == nil {
if name, ok := ref.(reference.Named); ok {
trimmed := reference.TrimNamed(name)
if imageRef, err3 := reference.WithDigest(trimmed, imageDigest); err3 == nil {
if _, ok := digestMap[imageRef.String()]; !ok {
repoDigests = append(repoDigests, imageRef.String())
digestMap[imageRef.String()] = struct{}{}
}
}
}
}
}
return imageDigest, repoDigests
}
func (svc *imageService) ListImages(systemContext *types.SystemContext, filter string) ([]ImageResult, error) {
results := []ImageResult{}
if filter != "" {
@ -94,16 +171,26 @@ func (svc *imageService) ListImages(systemContext *types.SystemContext, filter s
return nil, err
}
if image, err := istorage.Transport.GetStoreImage(svc.store, ref); err == nil {
img, err := ref.NewImage(systemContext)
img, err := ref.NewImageSource(systemContext)
if err != nil {
return nil, err
}
size := imageSize(img)
configDigest, err := imageConfigDigest(img, nil)
img.Close()
if err != nil {
return nil, err
}
name, tags, digests := sortNamesByType(image.Names)
imageDigest, repoDigests := svc.makeRepoDigests(digests, tags, image.ID)
results = append(results, ImageResult{
ID: image.ID,
Names: image.Names,
Size: size,
ID: image.ID,
Name: name,
RepoTags: tags,
RepoDigests: repoDigests,
Size: size,
Digest: imageDigest,
ConfigDigest: configDigest,
})
}
} else {
@ -116,16 +203,26 @@ func (svc *imageService) ListImages(systemContext *types.SystemContext, filter s
if err != nil {
return nil, err
}
img, err := ref.NewImage(systemContext)
img, err := ref.NewImageSource(systemContext)
if err != nil {
return nil, err
}
size := imageSize(img)
configDigest, err := imageConfigDigest(img, nil)
img.Close()
if err != nil {
return nil, err
}
name, tags, digests := sortNamesByType(image.Names)
imageDigest, repoDigests := svc.makeRepoDigests(digests, tags, image.ID)
results = append(results, ImageResult{
ID: image.ID,
Names: image.Names,
Size: size,
ID: image.ID,
Name: name,
RepoTags: tags,
RepoDigests: repoDigests,
Size: size,
Digest: imageDigest,
ConfigDigest: configDigest,
})
}
}
@ -150,29 +247,54 @@ func (svc *imageService) ImageStatus(systemContext *types.SystemContext, nameOrI
return nil, err
}
img, err := ref.NewImage(systemContext)
img, err := ref.NewImageSource(systemContext)
if err != nil {
return nil, err
}
defer img.Close()
size := imageSize(img)
configDigest, err := imageConfigDigest(img, nil)
if err != nil {
return nil, err
}
return &ImageResult{
name, tags, digests := sortNamesByType(image.Names)
imageDigest, repoDigests := svc.makeRepoDigests(digests, tags, image.ID)
result := ImageResult{
ID: image.ID,
Names: image.Names,
Name: name,
RepoTags: tags,
RepoDigests: repoDigests,
Size: size,
ConfigDigest: img.ConfigInfo().Digest,
}, nil
Digest: imageDigest,
ConfigDigest: configDigest,
}
return &result, nil
}
func imageSize(img types.Image) *uint64 {
if sum, err := img.Size(); err == nil {
usum := uint64(sum)
return &usum
func imageSize(img types.ImageSource) *uint64 {
if s, ok := img.(sizer); ok {
if sum, err := s.Size(); err == nil {
usum := uint64(sum)
return &usum
}
}
return nil
}
func imageConfigDigest(img types.ImageSource, instanceDigest *digest.Digest) (digest.Digest, error) {
manifestBytes, manifestType, err := img.GetManifest(instanceDigest)
if err != nil {
return "", err
}
imgManifest, err := manifest.FromBlob(manifestBytes, manifestType)
if err != nil {
return "", err
}
return imgManifest.ConfigInfo().Digest, nil
}
func (svc *imageService) CanPull(imageName string, options *copy.Options) (bool, error) {
srcRef, err := svc.prepareReference(imageName, options)
if err != nil {
@ -182,7 +304,11 @@ func (svc *imageService) CanPull(imageName string, options *copy.Options) (bool,
if err != nil {
return false, err
}
src, err := image.FromSource(rawSource)
sourceCtx := &types.SystemContext{}
if options.SourceCtx != nil {
sourceCtx = options.SourceCtx
}
src, err := image.FromSource(sourceCtx, rawSource)
if err != nil {
rawSource.Close()
return false, err
@ -272,6 +398,57 @@ func (svc *imageService) PullImage(systemContext *types.SystemContext, imageName
return destRef, nil
}
func (svc *imageService) UntagImage(systemContext *types.SystemContext, nameOrID string) error {
ref, err := alltransports.ParseImageName(nameOrID)
if err != nil {
ref2, err2 := istorage.Transport.ParseStoreReference(svc.store, "@"+nameOrID)
if err2 != nil {
ref3, err3 := istorage.Transport.ParseStoreReference(svc.store, nameOrID)
if err3 != nil {
return err
}
ref2 = ref3
}
ref = ref2
}
img, err := istorage.Transport.GetStoreImage(svc.store, ref)
if err != nil {
return err
}
if !strings.HasPrefix(img.ID, nameOrID) {
namedRef, err := svc.prepareReference(nameOrID, &copy.Options{})
if err != nil {
return err
}
name := nameOrID
if namedRef.DockerReference() != nil {
name = namedRef.DockerReference().Name()
if tagged, ok := namedRef.DockerReference().(reference.NamedTagged); ok {
name = name + ":" + tagged.Tag()
}
if canonical, ok := namedRef.DockerReference().(reference.Canonical); ok {
name = name + "@" + canonical.Digest().String()
}
}
prunedNames := make([]string, 0, len(img.Names))
for _, imgName := range img.Names {
if imgName != name && imgName != nameOrID {
prunedNames = append(prunedNames, imgName)
}
}
if len(prunedNames) > 0 {
return svc.store.SetNames(img.ID, prunedNames)
}
}
return ref.DeleteImage(systemContext)
}
func (svc *imageService) RemoveImage(systemContext *types.SystemContext, nameOrID string) error {
ref, err := alltransports.ParseImageName(nameOrID)
if err != nil {
@ -328,113 +505,35 @@ func (svc *imageService) isSecureIndex(indexName string) bool {
return true
}
func isValidHostname(hostname string) bool {
return hostname != "" && !strings.Contains(hostname, "/") &&
(strings.Contains(hostname, ".") ||
strings.Contains(hostname, ":") || hostname == "localhost")
}
func isReferenceFullyQualified(reposName reference.Named) bool {
indexName, _, _ := splitReposName(reposName)
return indexName != ""
}
const (
// defaultHostname is the default built-in hostname
defaultHostname = "docker.io"
// legacyDefaultHostname is automatically converted to DefaultHostname
legacyDefaultHostname = "index.docker.io"
// defaultRepoPrefix is the prefix used for default repositories in default host
defaultRepoPrefix = "library/"
)
// splitReposName breaks a reposName into an index name and remote name
func splitReposName(reposName reference.Named) (indexName string, remoteName reference.Named, err error) {
var remoteNameStr string
indexName, remoteNameStr = distreference.SplitHostname(reposName)
if !isValidHostname(indexName) {
// This is a Docker Index repos (ex: samalba/hipache or ubuntu)
// 'docker.io'
indexName = ""
remoteName = reposName
} else {
remoteName, err = withName(remoteNameStr)
}
return
}
func validateName(name string) error {
if err := validateID(strings.TrimPrefix(name, defaultHostname+"/")); err == nil {
return fmt.Errorf("Invalid repository name (%s), cannot specify 64-byte hexadecimal strings", name)
}
return nil
}
var validHex = regexp.MustCompile(`^([a-f0-9]{64})$`)
// validateID checks whether an ID string is a valid image ID.
func validateID(id string) error {
if ok := validHex.MatchString(id); !ok {
return fmt.Errorf("image ID %q is invalid", id)
}
return nil
}
// withName returns a named object representing the given string. If the input
// is invalid ErrReferenceInvalidFormat will be returned.
func withName(name string) (reference.Named, error) {
name, err := normalize(name)
if err != nil {
return nil, err
}
if err := validateName(name); err != nil {
return nil, err
}
r, err := distreference.WithName(name)
return r, err
}
// splitHostname splits a repository name to hostname and remotename string.
// If no valid hostname is found, empty string will be returned as a resulting
// hostname. Repository name needs to be already validated before.
func splitHostname(name string) (hostname, remoteName string) {
func splitDockerDomain(name string) (domain, remainder string) {
i := strings.IndexRune(name, '/')
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
hostname, remoteName = "", name
domain, remainder = "", name
} else {
hostname, remoteName = name[:i], name[i+1:]
}
if hostname == legacyDefaultHostname {
hostname = defaultHostname
}
if hostname == defaultHostname && !strings.ContainsRune(remoteName, '/') {
remoteName = defaultRepoPrefix + remoteName
domain, remainder = name[:i], name[i+1:]
}
return
}
// normalize returns a repository name in its normalized form, meaning it
// will contain library/ prefix for official images.
func normalize(name string) (string, error) {
host, remoteName := splitHostname(name)
if strings.ToLower(remoteName) != remoteName {
return "", errors.New("invalid reference format: repository name must be lowercase")
}
if host == defaultHostname {
if strings.HasPrefix(remoteName, defaultRepoPrefix) {
remoteName = strings.TrimPrefix(remoteName, defaultRepoPrefix)
}
return host + "/" + remoteName, nil
}
return name, nil
}
func (svc *imageService) ResolveNames(imageName string) ([]string, error) {
r, err := reference.ParseNormalizedNamed(imageName)
// _Maybe_ it's a truncated image ID. Don't prepend a registry name, then.
if len(imageName) >= minimumTruncatedIDLength && svc.store != nil {
if img, err := svc.store.Image(imageName); err == nil && img != nil && strings.HasPrefix(img.ID, imageName) {
// It's a truncated version of the ID of an image that's present in local storage;
// we need to expand it.
return []string{img.ID}, nil
}
}
// This to prevent any image ID to go through this routine
_, err := reference.ParseNormalizedNamed(imageName)
if err != nil {
if strings.Contains(err.Error(), "cannot specify 64-byte hexadecimal strings") {
return nil, ErrCannotParseImageID
}
return nil, err
}
if isReferenceFullyQualified(r) {
domain, remainder := splitDockerDomain(imageName)
if domain != "" {
// this means the image is already fully qualified
return []string{imageName}, nil
}
@ -446,10 +545,13 @@ func (svc *imageService) ResolveNames(imageName string) ([]string, error) {
// this means we got an image in the form of "busybox"
// we need to use additional registries...
// normalize the unqualified image to be domain/repo/image...
_, rest := splitDomain(r.Name())
images := []string{}
for _, r := range svc.registries {
images = append(images, filepath.Join(r, rest))
rem := remainder
if r == "docker.io" && !strings.ContainsRune(remainder, '/') {
rem = "library/" + rem
}
images = append(images, path.Join(r, rem))
}
return images, nil
}

View File

@ -1,125 +0,0 @@
package storage
// This is a fork of docker/distribution code to be used when manipulating image
// references.
// DO NOT EDIT THIS FILE.
import "regexp"
var (
// alphaNumericRegexp defines the alpha numeric atom, typically a
// component of names. This only allows lower case characters and digits.
alphaNumericRegexp = match(`[a-z0-9]+`)
// separatorRegexp defines the separators allowed to be embedded in name
// components. This allow one period, one or two underscore and multiple
// dashes.
separatorRegexp = match(`(?:[._]|__|[-]*)`)
// nameComponentRegexp restricts registry path component names to start
// with at least one letter or number, with following parts able to be
// separated by one period, one or two underscore and multiple dashes.
nameComponentRegexp = expression(
alphaNumericRegexp,
optional(repeated(separatorRegexp, alphaNumericRegexp)))
// domainComponentRegexp restricts the registry domain component of a
// repository name to start with a component as defined by domainRegexp
// and followed by an optional port.
domainComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`)
// domainRegexp defines the structure of potential domain components
// that may be part of image names. This is purposely a subset of what is
// allowed by DNS to ensure backwards compatibility with Docker image
// names.
domainRegexp = expression(
domainComponentRegexp,
optional(repeated(literal(`.`), domainComponentRegexp)),
optional(literal(`:`), match(`[0-9]+`)))
// NameRegexp is the format for the name component of references. The
// regexp has capturing groups for the domain and name part omitting
// the separating forward slash from either.
NameRegexp = expression(
optional(domainRegexp, literal(`/`)),
nameComponentRegexp,
optional(repeated(literal(`/`), nameComponentRegexp)))
// anchoredNameRegexp is used to parse a name value, capturing the
// domain and trailing components.
anchoredNameRegexp = anchored(
optional(capture(domainRegexp), literal(`/`)),
capture(nameComponentRegexp,
optional(repeated(literal(`/`), nameComponentRegexp))))
// IdentifierRegexp is the format for string identifier used as a
// content addressable identifier using sha256. These identifiers
// are like digests without the algorithm, since sha256 is used.
IdentifierRegexp = match(`([a-f0-9]{64})`)
// ShortIdentifierRegexp is the format used to represent a prefix
// of an identifier. A prefix may be used to match a sha256 identifier
// within a list of trusted identifiers.
ShortIdentifierRegexp = match(`([a-f0-9]{6,64})`)
)
// match compiles the string to a regular expression.
var match = regexp.MustCompile
// literal compiles s into a literal regular expression, escaping any regexp
// reserved characters.
func literal(s string) *regexp.Regexp {
re := match(regexp.QuoteMeta(s))
if _, complete := re.LiteralPrefix(); !complete {
panic("must be a literal")
}
return re
}
func splitDomain(name string) (string, string) {
match := anchoredNameRegexp.FindStringSubmatch(name)
if len(match) != 3 {
return "", name
}
return match[1], match[2]
}
// expression defines a full expression, where each regular expression must
// follow the previous.
func expression(res ...*regexp.Regexp) *regexp.Regexp {
var s string
for _, re := range res {
s += re.String()
}
return match(s)
}
// optional wraps the expression in a non-capturing group and makes the
// production optional.
func optional(res ...*regexp.Regexp) *regexp.Regexp {
return match(group(expression(res...)).String() + `?`)
}
// repeated wraps the regexp in a non-capturing group to get one or more
// matches.
func repeated(res ...*regexp.Regexp) *regexp.Regexp {
return match(group(expression(res...)).String() + `+`)
}
// group wraps the regexp in a non-capturing group.
func group(res ...*regexp.Regexp) *regexp.Regexp {
return match(`(?:` + expression(res...).String() + `)`)
}
// capture wraps the expression in a capturing group.
func capture(res ...*regexp.Regexp) *regexp.Regexp {
return match(`(` + expression(res...).String() + `)`)
}
// anchored anchors the regular expression by adding start and end delimiters.
func anchored(res ...*regexp.Regexp) *regexp.Regexp {
return match(`^` + expression(res...).String() + `$`)
}

84
pkg/storage/image_test.go Normal file
View File

@ -0,0 +1,84 @@
package storage
import (
"reflect"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestResolveNames(t *testing.T) {
cases := []struct {
name string
additionalRegistries []string
imageName string
expected []string
err bool
errContains string
}{
{
name: "test unqualified images get correctly qualified in order and correct tag",
additionalRegistries: []string{"testregistry.com", "registry.access.redhat.com", "docker.io"},
imageName: "openshift3/ose-deployer:sometag",
expected: []string{"testregistry.com/openshift3/ose-deployer:sometag", "registry.access.redhat.com/openshift3/ose-deployer:sometag", "docker.io/openshift3/ose-deployer:sometag"},
err: false,
},
{
name: "test unqualified images get correctly qualified in order and correct digest",
additionalRegistries: []string{"testregistry.com", "registry.access.redhat.com", "docker.io"},
imageName: "openshift3/ose-deployer@sha256:dc5f67a48da730d67bf4bfb8824ea8a51be26711de090d6d5a1ffff2723168a3",
expected: []string{"testregistry.com/openshift3/ose-deployer@sha256:dc5f67a48da730d67bf4bfb8824ea8a51be26711de090d6d5a1ffff2723168a3", "registry.access.redhat.com/openshift3/ose-deployer@sha256:dc5f67a48da730d67bf4bfb8824ea8a51be26711de090d6d5a1ffff2723168a3", "docker.io/openshift3/ose-deployer@sha256:dc5f67a48da730d67bf4bfb8824ea8a51be26711de090d6d5a1ffff2723168a3"},
err: false,
},
{
name: "test unqualified images get correctly qualified in order",
additionalRegistries: []string{"testregistry.com", "registry.access.redhat.com", "docker.io"},
imageName: "openshift3/ose-deployer:latest",
expected: []string{"testregistry.com/openshift3/ose-deployer:latest", "registry.access.redhat.com/openshift3/ose-deployer:latest", "docker.io/openshift3/ose-deployer:latest"},
err: false,
},
{
name: "test unqualified images get correctly qualified from official library",
additionalRegistries: []string{"testregistry.com", "registry.access.redhat.com", "docker.io"},
imageName: "nginx:latest",
expected: []string{"testregistry.com/nginx:latest", "registry.access.redhat.com/nginx:latest", "docker.io/library/nginx:latest"},
err: false,
},
{
name: "test qualified images returns just qualified",
additionalRegistries: []string{"testregistry.com", "registry.access.redhat.com", "docker.io"},
imageName: "mypersonalregistry.com/nginx:latest",
expected: []string{"mypersonalregistry.com/nginx:latest"},
err: false,
},
{
name: "test we don't have names w/o registries",
imageName: "openshift3/ose-deployer:latest",
err: true,
},
{
name: "test we cannot resolve names from an image ID",
imageName: "6ad733544a6317992a6fac4eb19fe1df577d4dec7529efec28a5bd0edad0fd30",
err: true,
errContains: "cannot parse an image ID",
},
}
for _, c := range cases {
svc := &imageService{
registries: c.additionalRegistries,
}
names, err := svc.ResolveNames(c.imageName)
if !c.err {
require.NoError(t, err, c.name)
if !reflect.DeepEqual(names, c.expected) {
t.Fatalf("Exepected: %v, Got: %v: %q", c.expected, names, c.name)
}
} else {
require.Error(t, err, c.name)
if c.errContains != "" {
assert.Contains(t, err.Error(), c.errContains)
}
}
}
}

View File

@ -3,10 +3,6 @@ package apparmor
const (
// DefaultApparmorProfile is the name of default apparmor profile name.
DefaultApparmorProfile = "crio-default"
// ContainerAnnotationKeyPrefix is the prefix to an annotation key specifying a container profile.
ContainerAnnotationKeyPrefix = "container.apparmor.security.beta.kubernetes.io/"
// ProfileRuntimeDefault is he profile specifying the runtime default.
ProfileRuntimeDefault = "runtime/default"
// ProfileNamePrefix is the prefix for specifying profiles loaded on the node.

View File

@ -34,7 +34,7 @@ type profileData struct {
// EnsureDefaultApparmorProfile loads default apparmor profile, if it is not loaded.
func EnsureDefaultApparmorProfile() error {
if apparmor.IsEnabled() {
if IsEnabled() {
loaded, err := IsLoaded(DefaultApparmorProfile)
if err != nil {
return fmt.Errorf("Could not check if %s AppArmor profile was loaded: %s", DefaultApparmorProfile, err)
@ -59,12 +59,6 @@ func IsEnabled() bool {
return apparmor.IsEnabled()
}
// GetProfileNameFromPodAnnotations gets the name of the profile to use with container from
// pod annotations
func GetProfileNameFromPodAnnotations(annotations map[string]string, containerName string) string {
return annotations[ContainerAnnotationKeyPrefix+containerName]
}
// InstallDefault generates a default profile in a temp directory determined by
// os.TempDir(), then loads the profile into the kernel using 'apparmor_parser'.
func InstallDefault(name string) error {

View File

@ -11,8 +11,3 @@ func IsEnabled() bool {
func EnsureDefaultApparmorProfile() error {
return nil
}
// GetProfileNameFromPodAnnotations dose nothing, when build without apparmor build tag.
func GetProfileNameFromPodAnnotations(annotations map[string]string, containerName string) string {
return ""
}

View File

@ -5,7 +5,7 @@ import (
"io/ioutil"
"github.com/BurntSushi/toml"
"github.com/kubernetes-incubator/cri-o/libkpod"
"github.com/kubernetes-incubator/cri-o/lib"
)
//CrioConfigPath is the default location for the conf file
@ -14,7 +14,7 @@ const CrioConfigPath = "/etc/crio/crio.conf"
// Config represents the entire set of configuration values that can be set for
// the server. This is intended to be loaded from a toml-encoded config file.
type Config struct {
libkpod.Config
lib.Config
APIConfig
}
@ -37,11 +37,11 @@ type APIConfig struct {
// conversions.
type tomlConfig struct {
Crio struct {
libkpod.RootConfig
API struct{ APIConfig } `toml:"api"`
Runtime struct{ libkpod.RuntimeConfig } `toml:"runtime"`
Image struct{ libkpod.ImageConfig } `toml:"image"`
Network struct{ libkpod.NetworkConfig } `toml:"network"`
lib.RootConfig
API struct{ APIConfig } `toml:"api"`
Runtime struct{ lib.RuntimeConfig } `toml:"runtime"`
Image struct{ lib.ImageConfig } `toml:"image"`
Network struct{ lib.NetworkConfig } `toml:"network"`
} `toml:"crio"`
}
@ -102,9 +102,9 @@ func (c *Config) ToFile(path string) error {
// DefaultConfig returns the default configuration for crio.
func DefaultConfig() *Config {
return &Config{
Config: *libkpod.DefaultConfig(),
Config: *lib.DefaultConfig(),
APIConfig: APIConfig{
Listen: "/var/run/crio.sock",
Listen: "/var/run/crio/crio.sock",
StreamAddress: "",
StreamPort: "10010",
},

89
server/config_test.go Normal file
View File

@ -0,0 +1,89 @@
package server
import (
"io/ioutil"
"os"
"testing"
"github.com/kubernetes-incubator/cri-o/lib"
)
const fixturePath = "fixtures/crio.conf"
func must(t *testing.T, err error) {
if err != nil {
t.Error(err)
}
}
func assertAllFieldsEquality(t *testing.T, c Config) {
testCases := []struct {
fieldValue, expected interface{}
}{
{c.RootConfig.Root, "/var/lib/containers/storage"},
{c.RootConfig.RunRoot, "/var/run/containers/storage"},
{c.RootConfig.Storage, "overlay"},
{c.RootConfig.StorageOptions[0], "overlay.override_kernel_check=1"},
{c.APIConfig.Listen, "/var/run/crio.sock"},
{c.APIConfig.StreamPort, "10010"},
{c.APIConfig.StreamAddress, "localhost"},
{c.RuntimeConfig.Runtime, "/usr/local/bin/runc"},
{c.RuntimeConfig.RuntimeUntrustedWorkload, "untrusted"},
{c.RuntimeConfig.DefaultWorkloadTrust, "trusted"},
{c.RuntimeConfig.Conmon, "/usr/local/libexec/crio/conmon"},
{c.RuntimeConfig.ConmonEnv[0], "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
{c.RuntimeConfig.SELinux, true},
{c.RuntimeConfig.SeccompProfile, "/etc/crio/seccomp.json"},
{c.RuntimeConfig.ApparmorProfile, "crio-default"},
{c.RuntimeConfig.CgroupManager, "cgroupfs"},
{c.RuntimeConfig.PidsLimit, int64(1024)},
{c.ImageConfig.DefaultTransport, "docker://"},
{c.ImageConfig.PauseImage, "kubernetes/pause"},
{c.ImageConfig.PauseCommand, "/pause"},
{c.ImageConfig.SignaturePolicyPath, "/tmp"},
{c.ImageConfig.ImageVolumes, lib.ImageVolumesType("mkdir")},
{c.ImageConfig.InsecureRegistries[0], "insecure-registry:1234"},
{c.ImageConfig.Registries[0], "registry:4321"},
{c.NetworkConfig.NetworkDir, "/etc/cni/net.d/"},
{c.NetworkConfig.PluginDir, "/opt/cni/bin/"},
}
for _, tc := range testCases {
if tc.fieldValue != tc.expected {
t.Errorf(`Expecting: "%s", got: "%s"`, tc.expected, tc.fieldValue)
}
}
}
func TestUpdateFromFile(t *testing.T) {
c := Config{}
must(t, c.UpdateFromFile(fixturePath))
assertAllFieldsEquality(t, c)
}
func TestToFile(t *testing.T) {
configFromFixture := Config{}
must(t, configFromFixture.UpdateFromFile(fixturePath))
f, err := ioutil.TempFile("", "crio.conf")
if err != nil {
t.Error(err)
}
defer os.Remove(f.Name())
must(t, configFromFixture.ToFile(f.Name()))
writtenConfig := Config{}
err = writtenConfig.UpdateFromFile(f.Name())
if err != nil {
t.Fatal(err)
}
assertAllFieldsEquality(t, writtenConfig)
}

View File

@ -14,12 +14,11 @@ import (
"strings"
"time"
"github.com/docker/distribution/reference"
dockermounts "github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/symlink"
"github.com/kubernetes-incubator/cri-o/libkpod"
"github.com/kubernetes-incubator/cri-o/libkpod/sandbox"
"github.com/kubernetes-incubator/cri-o/lib"
"github.com/kubernetes-incubator/cri-o/lib/sandbox"
"github.com/kubernetes-incubator/cri-o/oci"
"github.com/kubernetes-incubator/cri-o/pkg/annotations"
"github.com/kubernetes-incubator/cri-o/pkg/storage"
@ -234,11 +233,11 @@ func addImageVolumes(rootfs string, s *Server, containerInfo *storage.ContainerI
return nil, err
}
switch s.config.ImageVolumes {
case libkpod.ImageVolumesMkdir:
case lib.ImageVolumesMkdir:
if err1 := os.MkdirAll(fp, 0644); err1 != nil {
return nil, err1
}
case libkpod.ImageVolumesBind:
case lib.ImageVolumesBind:
volumeDirName := stringid.GenerateNonCryptoID()
src := filepath.Join(containerInfo.RunDir, "mounts", volumeDirName)
if err1 := os.MkdirAll(src, 0644); err1 != nil {
@ -258,7 +257,7 @@ func addImageVolumes(rootfs string, s *Server, containerInfo *storage.ContainerI
Options: []string{"rw"},
})
case libkpod.ImageVolumesIgnore:
case lib.ImageVolumesIgnore:
logrus.Debugf("Ignoring volume %v", dest)
default:
logrus.Fatalf("Unrecognized image volumes setting")
@ -424,18 +423,21 @@ func buildOCIProcessArgs(containerKubeConfig *pb.ContainerConfig, imageOCIConfig
}
// addOCIHook look for hooks programs installed in hooksDirPath and add them to spec
func addOCIHook(specgen *generate.Generator, hook libkpod.HookParams) error {
func addOCIHook(specgen *generate.Generator, hook lib.HookParams) error {
logrus.Debugf("AddOCIHook", hook)
for _, stage := range hook.Stage {
h := rspec.Hook{
Path: hook.Hook,
Args: append([]string{hook.Hook}, hook.Arguments...),
Env: []string{fmt.Sprintf("stage=%s", stage)},
}
switch stage {
case "prestart":
specgen.AddPreStartHook(hook.Hook, []string{hook.Hook, "prestart"})
specgen.AddPreStartHook(h)
case "poststart":
specgen.AddPostStartHook(hook.Hook, []string{hook.Hook, "poststart"})
specgen.AddPostStartHook(h)
case "poststop":
specgen.AddPostStopHook(hook.Hook, []string{hook.Hook, "poststop"})
specgen.AddPostStopHook(h)
}
}
return nil
@ -488,6 +490,110 @@ func setupContainerUser(specgen *generate.Generator, rootfs string, sc *pb.Linux
return nil
}
// setupCapabilities sets process.capabilities in the OCI runtime config.
func setupCapabilities(specgen *generate.Generator, capabilities *pb.Capability) error {
if capabilities == nil {
return nil
}
toCAPPrefixed := func(cap string) string {
if !strings.HasPrefix(strings.ToLower(cap), "cap_") {
return "CAP_" + strings.ToUpper(cap)
}
return cap
}
// Add/drop all capabilities if "all" is specified, so that
// following individual add/drop could still work. E.g.
// AddCapabilities: []string{"ALL"}, DropCapabilities: []string{"CHOWN"}
// will be all capabilities without `CAP_CHOWN`.
// see https://github.com/kubernetes/kubernetes/issues/51980
if inStringSlice(capabilities.GetAddCapabilities(), "ALL") {
for _, c := range getOCICapabilitiesList() {
if err := specgen.AddProcessCapabilityAmbient(c); err != nil {
return err
}
if err := specgen.AddProcessCapabilityBounding(c); err != nil {
return err
}
if err := specgen.AddProcessCapabilityEffective(c); err != nil {
return err
}
if err := specgen.AddProcessCapabilityInheritable(c); err != nil {
return err
}
if err := specgen.AddProcessCapabilityPermitted(c); err != nil {
return err
}
}
}
if inStringSlice(capabilities.GetDropCapabilities(), "ALL") {
for _, c := range getOCICapabilitiesList() {
if err := specgen.DropProcessCapabilityAmbient(c); err != nil {
return err
}
if err := specgen.DropProcessCapabilityBounding(c); err != nil {
return err
}
if err := specgen.DropProcessCapabilityEffective(c); err != nil {
return err
}
if err := specgen.DropProcessCapabilityInheritable(c); err != nil {
return err
}
if err := specgen.DropProcessCapabilityPermitted(c); err != nil {
return err
}
}
}
for _, cap := range capabilities.GetAddCapabilities() {
if strings.ToUpper(cap) == "ALL" {
continue
}
capPrefixed := toCAPPrefixed(cap)
if err := specgen.AddProcessCapabilityAmbient(capPrefixed); err != nil {
return err
}
if err := specgen.AddProcessCapabilityBounding(capPrefixed); err != nil {
return err
}
if err := specgen.AddProcessCapabilityEffective(capPrefixed); err != nil {
return err
}
if err := specgen.AddProcessCapabilityInheritable(capPrefixed); err != nil {
return err
}
if err := specgen.AddProcessCapabilityPermitted(capPrefixed); err != nil {
return err
}
}
for _, cap := range capabilities.GetDropCapabilities() {
if strings.ToUpper(cap) == "ALL" {
continue
}
capPrefixed := toCAPPrefixed(cap)
if err := specgen.DropProcessCapabilityAmbient(capPrefixed); err != nil {
return fmt.Errorf("failed to drop cap %s %v", capPrefixed, err)
}
if err := specgen.DropProcessCapabilityBounding(capPrefixed); err != nil {
return fmt.Errorf("failed to drop cap %s %v", capPrefixed, err)
}
if err := specgen.DropProcessCapabilityEffective(capPrefixed); err != nil {
return fmt.Errorf("failed to drop cap %s %v", capPrefixed, err)
}
if err := specgen.DropProcessCapabilityInheritable(capPrefixed); err != nil {
return fmt.Errorf("failed to drop cap %s %v", capPrefixed, err)
}
if err := specgen.DropProcessCapabilityPermitted(capPrefixed); err != nil {
return fmt.Errorf("failed to drop cap %s %v", capPrefixed, err)
}
}
return nil
}
func hostNetwork(containerConfig *pb.ContainerConfig) bool {
securityContext := containerConfig.GetLinux().GetSecurityContext()
if securityContext == nil || securityContext.GetNamespaceOptions() == nil {
@ -563,7 +669,11 @@ func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerReq
return nil, fmt.Errorf("CreateContainerRequest.ContainerConfig is nil")
}
name := containerConfig.GetMetadata().Name
if containerConfig.GetMetadata() == nil {
return nil, fmt.Errorf("CreateContainerRequest.ContainerConfig.Metadata is nil")
}
name := containerConfig.GetMetadata().GetName()
if name == "" {
return nil, fmt.Errorf("CreateContainerRequest.ContainerConfig.Name is empty")
}
@ -616,7 +726,7 @@ func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerReq
func (s *Server) setupOCIHooks(specgen *generate.Generator, sb *sandbox.Sandbox, containerConfig *pb.ContainerConfig, command string) error {
mounts := containerConfig.GetMounts()
addedHooks := map[string]struct{}{}
addHook := func(hook libkpod.HookParams) error {
addHook := func(hook lib.HookParams) error {
// Only add a hook once
if _, ok := addedHooks[hook.Hook]; !ok {
if err := addOCIHook(specgen, hook); err != nil {
@ -711,8 +821,14 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
}
specgen.AddAnnotation(annotations.Volumes, string(volumesJSON))
mnt := rspec.Mount{
Destination: "/sys/fs/cgroup",
Type: "cgroup",
Source: "cgroup",
Options: []string{"nosuid", "noexec", "nodev", "relatime", "ro"},
}
// Add cgroup mount so container process can introspect its own limits
specgen.AddCgroupsMount("ro")
specgen.AddMount(mnt)
if err := addDevices(sb, containerConfig, &specgen); err != nil {
return nil, err
@ -740,7 +856,8 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
// set this container's apparmor profile if it is set by sandbox
if s.appArmorEnabled && !privileged {
appArmorProfileName := s.getAppArmorProfileName(sb.Annotations(), metadata.Name)
appArmorProfileName := s.getAppArmorProfileName(containerConfig.GetLinux().GetSecurityContext().GetApparmorProfile())
if appArmorProfileName != "" {
// reload default apparmor profile if it is unloaded.
if s.appArmorProfile == apparmor.DefaultApparmorProfile {
@ -751,6 +868,7 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
specgen.SetProcessApparmorProfile(appArmorProfileName)
}
}
logPath := containerConfig.LogPath
@ -784,28 +902,13 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
if linux != nil {
resources := linux.GetResources()
if resources != nil {
cpuPeriod := resources.CpuPeriod
if cpuPeriod != 0 {
specgen.SetLinuxResourcesCPUPeriod(uint64(cpuPeriod))
}
cpuQuota := resources.CpuQuota
if cpuQuota != 0 {
specgen.SetLinuxResourcesCPUQuota(cpuQuota)
}
cpuShares := resources.CpuShares
if cpuShares != 0 {
specgen.SetLinuxResourcesCPUShares(uint64(cpuShares))
}
memoryLimit := resources.MemoryLimitInBytes
if memoryLimit != 0 {
specgen.SetLinuxResourcesMemoryLimit(memoryLimit)
}
oomScoreAdj := resources.OomScoreAdj
specgen.SetProcessOOMScoreAdj(int(oomScoreAdj))
specgen.SetLinuxResourcesCPUPeriod(uint64(resources.GetCpuPeriod()))
specgen.SetLinuxResourcesCPUQuota(resources.GetCpuQuota())
specgen.SetLinuxResourcesCPUShares(uint64(resources.GetCpuShares()))
specgen.SetLinuxResourcesMemoryLimit(resources.GetMemoryLimitInBytes())
specgen.SetProcessOOMScoreAdj(int(resources.GetOomScoreAdj()))
specgen.SetLinuxResourcesCPUCpus(resources.GetCpusetCpus())
specgen.SetLinuxResourcesCPUMems(resources.GetCpusetMems())
}
var cgPath string
@ -824,57 +927,13 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
}
specgen.SetLinuxCgroupsPath(cgPath)
capabilities := linux.GetSecurityContext().GetCapabilities()
if privileged {
// this is setting correct capabilities as well for privileged mode
specgen.SetupPrivileged(true)
setOCIBindMountsPrivileged(&specgen)
} else {
toCAPPrefixed := func(cap string) string {
if !strings.HasPrefix(strings.ToLower(cap), "cap_") {
return "CAP_" + strings.ToUpper(cap)
}
return cap
}
// Add/drop all capabilities if "all" is specified, so that
// following individual add/drop could still work. E.g.
// AddCapabilities: []string{"ALL"}, DropCapabilities: []string{"CHOWN"}
// will be all capabilities without `CAP_CHOWN`.
// see https://github.com/kubernetes/kubernetes/issues/51980
if inStringSlice(capabilities.GetAddCapabilities(), "ALL") {
for _, c := range getOCICapabilitiesList() {
if err := specgen.AddProcessCapability(c); err != nil {
return nil, err
}
}
}
if inStringSlice(capabilities.GetDropCapabilities(), "ALL") {
for _, c := range getOCICapabilitiesList() {
if err := specgen.DropProcessCapability(c); err != nil {
return nil, err
}
}
}
if capabilities != nil {
for _, cap := range capabilities.GetAddCapabilities() {
if strings.ToUpper(cap) == "ALL" {
continue
}
if err := specgen.AddProcessCapability(toCAPPrefixed(cap)); err != nil {
return nil, err
}
}
for _, cap := range capabilities.GetDropCapabilities() {
if strings.ToUpper(cap) == "ALL" {
continue
}
if err := specgen.DropProcessCapability(toCAPPrefixed(cap)); err != nil {
return nil, fmt.Errorf("failed to drop cap %s %v", toCAPPrefixed(cap), err)
}
}
err = setupCapabilities(&specgen, linux.GetSecurityContext().GetCapabilities())
if err != nil {
return nil, err
}
}
specgen.SetProcessSelinuxLabel(processLabel)
@ -889,6 +948,7 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware",
} {
specgen.AddLinuxMaskedPaths(mp)
@ -921,9 +981,15 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
return nil, err
}
// Do not share pid ns for now
if containerConfig.GetLinux().GetSecurityContext().GetNamespaceOptions().GetHostPid() {
// kubernetes PodSpec specify to use Host PID namespace
specgen.RemoveLinuxNamespace(string(rspec.PIDNamespace))
} else if s.config.EnableSharedPIDNamespace {
// share Pod PID namespace
pidNsPath := fmt.Sprintf("/proc/%d/ns/pid", podInfraState.Pid)
if err := specgen.AddOrReplaceLinuxNamespace(string(rspec.PIDNamespace), pidNsPath); err != nil {
return nil, err
}
}
netNsPath := sb.NetNsPath()
@ -948,53 +1014,37 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
}
images, err := s.StorageImageServer().ResolveNames(image)
if err != nil {
// This means we got an image ID
if strings.Contains(err.Error(), "cannot specify 64-byte hexadecimal strings") {
if err == storage.ErrCannotParseImageID {
images = append(images, image)
} else {
return nil, err
}
}
image = images[0]
// Get imageName and imageRef that are requested in container status
imageName := image
status, err := s.StorageImageServer().ImageStatus(s.ImageContext(), image)
// Get imageName and imageRef that are later requested in container status
status, err := s.StorageImageServer().ImageStatus(s.ImageContext(), images[0])
if err != nil {
return nil, err
}
imageName := status.Name
imageRef := status.ID
//
// TODO: https://github.com/kubernetes-incubator/cri-o/issues/531
//
//for _, n := range status.Names {
//r, err := reference.ParseNormalizedNamed(n)
//if err != nil {
//return nil, fmt.Errorf("failed to normalize image name for ImageRef: %v", err)
//}
//if digested, isDigested := r.(reference.Canonical); isDigested {
//imageRef = reference.FamiliarString(digested)
//break
//}
//}
for _, n := range status.Names {
r, err := reference.ParseNormalizedNamed(n)
if err != nil {
return nil, fmt.Errorf("failed to normalize image name for Image: %v", err)
}
if tagged, isTagged := r.(reference.Tagged); isTagged {
imageName = reference.FamiliarString(tagged)
break
}
if len(status.RepoDigests) > 0 {
imageRef = status.RepoDigests[0]
}
specgen.AddAnnotation(annotations.Image, image)
specgen.AddAnnotation(annotations.ImageName, imageName)
specgen.AddAnnotation(annotations.ImageRef, imageRef)
specgen.AddAnnotation(annotations.IP, sb.IP())
mnt = rspec.Mount{
Type: "bind",
Source: sb.ShmPath(),
Destination: "/etc/shm",
Options: []string{"rw", "bind"},
}
// bind mount the pod shm
specgen.AddBindMount(sb.ShmPath(), "/dev/shm", []string{"rw"})
specgen.AddMount(mnt)
options := []string{"rw"}
if readOnlyRootfs {
@ -1005,8 +1055,14 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
return nil, err
}
mnt = rspec.Mount{
Type: "bind",
Source: sb.ResolvPath(),
Destination: "/etc/resolv.conf",
Options: append(options, "bind"),
}
// bind mount the pod resolver file
specgen.AddBindMount(sb.ResolvPath(), "/etc/resolv.conf", options)
specgen.AddMount(mnt)
}
if sb.HostnamePath() != "" {
@ -1014,12 +1070,24 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
return nil, err
}
specgen.AddBindMount(sb.HostnamePath(), "/etc/hostname", options)
mnt = rspec.Mount{
Type: "bind",
Source: sb.HostnamePath(),
Destination: "/etc/hostname",
Options: append(options, "bind"),
}
specgen.AddMount(mnt)
}
// Bind mount /etc/hosts for host networking containers
if hostNetwork(containerConfig) {
specgen.AddBindMount("/etc/hosts", "/etc/hosts", options)
mnt = rspec.Mount{
Type: "bind",
Source: "/etc/hosts",
Destination: "/etc/hosts",
Options: append(options, "bind"),
}
specgen.AddMount(mnt)
}
// Set hostname and add env for hostname
@ -1035,7 +1103,6 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
specgen.AddAnnotation(annotations.TTY, fmt.Sprintf("%v", containerConfig.Tty))
specgen.AddAnnotation(annotations.Stdin, fmt.Sprintf("%v", containerConfig.Stdin))
specgen.AddAnnotation(annotations.StdinOnce, fmt.Sprintf("%v", containerConfig.StdinOnce))
specgen.AddAnnotation(annotations.Image, image)
specgen.AddAnnotation(annotations.ResolvPath, sb.InfraContainer().CrioAnnotations()[annotations.ResolvPath])
created := time.Now()
@ -1066,13 +1133,12 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
}
}
specgen.AddAnnotation(annotations.SeccompProfilePath, spp)
// TODO(runcom): add spp to container...
metaname := metadata.Name
attempt := metadata.Attempt
containerInfo, err := s.StorageRuntimeServer().CreateContainer(s.ImageContext(),
sb.Name(), sb.ID(),
image, image,
image, status.ID,
containerName, containerID,
metaname,
attempt,
@ -1081,6 +1147,14 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
if err != nil {
return nil, err
}
defer func() {
if err != nil {
err2 := s.StorageRuntimeServer().DeleteContainer(containerInfo.ID)
if err2 != nil {
logrus.Warnf("Failed to cleanup container directory: %v", err2)
}
}
}()
mountPoint, err := s.StorageRuntimeServer().StartContainer(containerID)
if err != nil {
@ -1090,7 +1164,8 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
containerImageConfig := containerInfo.Config
if containerImageConfig == nil {
return nil, fmt.Errorf("empty image config for %s", image)
err = fmt.Errorf("empty image config for %s", image)
return nil, err
}
if containerImageConfig.Config.StopSignal != "" {
@ -1110,30 +1185,10 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
}
specgen.SetProcessArgs(processArgs)
// Add environment variables from CRI and image config
envs := containerConfig.GetEnvs()
if envs != nil {
for _, item := range envs {
key := item.Key
value := item.Value
if key == "" {
continue
}
specgen.AddProcessEnv(key, value)
}
}
if containerImageConfig != nil {
for _, item := range containerImageConfig.Config.Env {
parts := strings.SplitN(item, "=", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid env from image: %s", item)
}
if parts[0] == "" {
continue
}
specgen.AddProcessEnv(parts[0], parts[1])
}
envs := mergeEnvs(containerImageConfig, containerConfig.GetEnvs())
for _, e := range envs {
parts := strings.SplitN(e, "=", 2)
specgen.AddProcessEnv(parts[0], parts[1])
}
// Set working directory
@ -1174,7 +1229,13 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
sort.Sort(orderedMounts(mounts))
for _, m := range mounts {
specgen.AddBindMount(m.Source, m.Destination, m.Options)
mnt = rspec.Mount{
Type: "bind",
Source: m.Source,
Destination: m.Destination,
Options: append(m.Options, "bind"),
}
specgen.AddMount(mnt)
}
if err := s.setupOCIHooks(&specgen, sb, containerConfig, processArgs[0]); err != nil {
@ -1213,6 +1274,7 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
}
container.SetSpec(specgen.Spec())
container.SetMountPoint(mountPoint)
container.SetSeccompProfilePath(spp)
for _, cv := range containerVolumes {
container.AddVolume(cv)
@ -1253,9 +1315,7 @@ func (s *Server) setupSeccomp(specgen *generate.Generator, profile string) error
}
// getAppArmorProfileName gets the profile name for the given container.
func (s *Server) getAppArmorProfileName(annotations map[string]string, ctrName string) string {
profile := apparmor.GetProfileNameFromPodAnnotations(annotations, ctrName)
func (s *Server) getAppArmorProfileName(profile string) string {
if profile == "" {
return ""
}

View File

@ -53,12 +53,15 @@ func (ss streamService) Exec(containerID string, cmd []string, stdin io.Reader,
return fmt.Errorf("container is not created or running")
}
args := []string{"exec"}
if tty {
args = append(args, "-t")
processFile, err := oci.PrepareProcessExec(c, cmd, tty)
if err != nil {
return err
}
defer os.RemoveAll(processFile.Name())
args := []string{"exec"}
args = append(args, "--process", processFile.Name())
args = append(args, c.ID())
args = append(args, cmd...)
execCmd := exec.Command(ss.runtimeServer.Runtime().Path(c), args...)
var cmdErr error
if tty {

View File

@ -97,6 +97,7 @@ func (s *Server) ListContainers(ctx context.Context, req *pb.ListContainersReque
Metadata: ctr.Metadata(),
Annotations: ctr.Annotations(),
Image: img,
ImageRef: ctr.ImageRef(),
}
switch cState.Status {

View File

@ -3,6 +3,7 @@ package server
import (
"time"
"github.com/containers/image/types"
"github.com/kubernetes-incubator/cri-o/oci"
"github.com/sirupsen/logrus"
"golang.org/x/net/context"
@ -38,7 +39,10 @@ func (s *Server) ContainerStatus(ctx context.Context, req *pb.ContainerStatusReq
ImageRef: c.ImageRef(),
},
}
resp.Status.Image = &pb.ImageSpec{Image: c.ImageName()}
resp.Status.Image = &pb.ImageSpec{Image: c.Image()}
if status, err := s.StorageImageServer().ImageStatus(&types.SystemContext{}, c.ImageRef()); err == nil {
resp.Status.Image.Image = status.Name
}
mounts := []*pb.Mount{}
for _, cv := range c.Volumes() {

41
server/fixtures/crio.conf Normal file
View File

@ -0,0 +1,41 @@
[crio]
root = "/var/lib/containers/storage"
runroot = "/var/run/containers/storage"
storage_driver = "overlay"
storage_option = ["overlay.override_kernel_check=1"]
[crio.api]
listen = "/var/run/crio.sock"
stream_address = "localhost"
stream_port = "10010"
[crio.runtime]
runtime = "/usr/local/bin/runc"
runtime_untrusted_workload = "untrusted"
default_workload_trust = "trusted"
conmon = "/usr/local/libexec/crio/conmon"
conmon_env = [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
]
selinux = true
seccomp_profile = "/etc/crio/seccomp.json"
apparmor_profile = "crio-default"
cgroup_manager = "cgroupfs"
pids_limit = 1024
[crio.image]
default_transport = "docker://"
pause_image = "kubernetes/pause"
pause_command = "/pause"
signature_policy = "/tmp"
image_volumes = "mkdir"
insecure_registries = [
"insecure-registry:1234",
]
registries = [
"registry:4321",
]
[crio.network]
network_dir = "/etc/cni/net.d/"
plugin_dir = "/opt/cni/bin/"

View File

@ -0,0 +1,4 @@
search 192.30.253.113 192.30.252.153
nameserver cri-o.io
nameserver github.com
options timeout:5 attempts:3

View File

@ -0,0 +1 @@
secretDataA

View File

@ -0,0 +1 @@
secretDataB

View File

@ -33,14 +33,16 @@ func (s *Server) ListImages(ctx context.Context, req *pb.ListImagesRequest) (res
for _, result := range results {
if result.Size != nil {
resp.Images = append(resp.Images, &pb.Image{
Id: result.ID,
RepoTags: result.Names,
Size_: *result.Size,
Id: result.ID,
RepoTags: result.RepoTags,
RepoDigests: result.RepoDigests,
Size_: *result.Size,
})
} else {
resp.Images = append(resp.Images, &pb.Image{
Id: result.ID,
RepoTags: result.Names,
Id: result.ID,
RepoTags: result.RepoTags,
RepoDigests: result.RepoDigests,
})
}
}

View File

@ -104,8 +104,16 @@ func (s *Server) PullImage(ctx context.Context, req *pb.PullImageRequest) (resp
if pulled == "" && err != nil {
return nil, err
}
status, err := s.StorageImageServer().ImageStatus(s.ImageContext(), pulled)
if err != nil {
return nil, err
}
imageRef := status.ID
if len(status.RepoDigests) > 0 {
imageRef = status.RepoDigests[0]
}
resp = &pb.PullImageResponse{
ImageRef: pulled,
ImageRef: imageRef,
}
logrus.Debugf("PullImageResponse: %+v", resp)
return resp, nil

Some files were not shown because too many files have changed in this diff Show More