diff --git a/packages/addons/addon-depends/go/package.mk b/packages/addons/addon-depends/go/package.mk new file mode 100644 index 0000000000..742a38cc05 --- /dev/null +++ b/packages/addons/addon-depends/go/package.mk @@ -0,0 +1,60 @@ +################################################################################ +# This file is part of LibreELEC - http://www.libreelec.tv +# Copyright (C) 2009-2016 Lukas Rusak (lrusak@libreelec.tv) +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +PKG_NAME="go" +PKG_VERSION="1.6" +PKG_REV="1" +PKG_ARCH="any" +PKG_LICENSE="BSD" +PKG_SITE="https://golang.org" +PKG_URL="https://github.com/golang/go/archive/${PKG_NAME}${PKG_VERSION}.tar.gz" +PKG_SOURCE_DIR="${PKG_NAME}-${PKG_NAME}${PKG_VERSION}" +PKG_DEPENDS_HOST="toolchain" +PKG_PRIORITY="optional" +PKG_SECTION="system" +PKG_SHORTDESC="Go is an open source programming language that makes it easy to build simple, reliable, and efficient software." +PKG_LONGDESC="Go is an open source programming language that makes it easy to build simple, reliable, and efficient software." + +PKG_IS_ADDON="no" +PKG_AUTORECONF="no" + +#################################################################### +# On Fedora `dnf install golang` will install go to /usr/lib/golang +# +# On Ubuntu you need to install golang manually, similar to: +# $ wget https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz +# $ tar xf go1.6.linux-amd64.tar.gz -C /opt/ +# $ ln -s /opt/go /usr/lib/golang +#################################################################### + +configure_host() { + export GOOS=linux + export GOROOT_FINAL=$ROOT/$TOOLCHAIN/lib/golang + export GOROOT_BOOTSTRAP=/usr/lib/golang + export GOARCH=amd64 +} + +make_host() { + cd $ROOT/$PKG_BUILD/src + bash make.bash --no-banner +} + +makeinstall_host() { + mkdir -p $ROOT/$TOOLCHAIN/lib/golang + cp -av $ROOT/$PKG_BUILD/* $ROOT/$TOOLCHAIN/lib/golang/ +} diff --git a/packages/addons/service/docker/changelog.txt b/packages/addons/service/docker/changelog.txt new file mode 100644 index 0000000000..f9dfb73a63 --- /dev/null +++ b/packages/addons/service/docker/changelog.txt @@ -0,0 +1,2 @@ +7.0.100 +- Initial release diff --git a/packages/addons/service/docker/icon/icon.png b/packages/addons/service/docker/icon/icon.png new file mode 100644 index 0000000000..c9f07eb63b Binary files /dev/null and b/packages/addons/service/docker/icon/icon.png differ diff --git a/packages/addons/service/docker/package.mk b/packages/addons/service/docker/package.mk new file mode 100644 index 0000000000..6ed609d86a --- /dev/null +++ b/packages/addons/service/docker/package.mk @@ -0,0 +1,96 @@ +################################################################################ +# This file is part of LibreELEC - http://www.libreelec.tv +# Copyright (C) 2009-2016 Lukas Rusak (lrusak@libreelec.tv) +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +PKG_NAME="docker" +PKG_VERSION="1.10.3" +PKG_REV="100" +PKG_ARCH="any" +PKG_ADDON_PROJECTS="Generic RPi RPi2" +PKG_LICENSE="ASL" +PKG_SITE="http://www.docker.com/" +PKG_URL="https://github.com/docker/docker/archive/v${PKG_VERSION}.tar.gz" +PKG_DEPENDS_TARGET="toolchain sqlite go:host" +PKG_PRIORITY="optional" +PKG_SECTION="service/system" +PKG_SHORTDESC="Docker is an open-source engine that automates the deployment of any application as a lightweight, portable, self-sufficient container that will run virtually anywhere." +PKG_LONGDESC="Docker containers can encapsulate any payload, and will run consistently on and between virtually any server. The same container that a developer builds and tests on a laptop will run at scale, in production*, on VMs, bare-metal servers, OpenStack clusters, public instances, or combinations of the above." +PKG_AUTORECONF="no" + +PKG_IS_ADDON="yes" +PKG_ADDON_NAME="Docker" +PKG_ADDON_TYPE="xbmc.service" +PKG_ADDON_REPOVERSION="7.0" + +configure_target() { + export DOCKER_BUILDTAGS="daemon \ + exclude_graphdriver_devicemapper \ + exclude_graphdriver_aufs \ + exclude_graphdriver_btrfs" + + case $TARGET_ARCH in + x86_64) + export GOARCH=amd64 + ;; + arm) + export GOARCH=arm + + case $TARGET_CPU in + arm1176jzf-s) + export GOARM=6 + ;; + cortex-a7) + export GOARM=7 + ;; + esac + ;; + esac + + export GOOS=linux + export CGO_ENABLED=1 + export CGO_NO_EMULATION=1 + export CGO_CFLAGS=$CFLAGS + export LDFLAGS="-w -linkmode external -extldflags -Wl,--unresolved-symbols=ignore-in-shared-libs -extld $TARGET_CC" + export GOLANG=$ROOT/$TOOLCHAIN/lib/golang/bin/go + export GOPATH=$ROOT/$PKG_BUILD/.gopath:$ROOT/$PKG_BUILD/vendor + export GOROOT=$ROOT/$TOOLCHAIN/lib/golang + export PATH=$PATH:$GOROOT/bin + + ./hack/vendor.sh + + ln -fs $ROOT/$PKG_BUILD $ROOT/$PKG_BUILD/vendor/src/github.com/docker/docker + + # used for docker version + export GITCOMMIT=$PKG_VERSION + export VERSION=$PKG_VERSION + export BUILDTIME="$(date --utc)" + bash ./hack/make/.go-autogen +} + +make_target() { + mkdir -p bin + $GOLANG build -v -o bin/docker -a -tags "$DOCKER_BUILDTAGS" -ldflags "$LDFLAGS" ./docker +} + +makeinstall_target() { + : +} + +addon() { + mkdir -p $ADDON_BUILD/$PKG_ADDON_ID/bin/ + cp -a $ROOT/$PKG_BUILD/bin/docker $ADDON_BUILD/$PKG_ADDON_ID/bin/ +} diff --git a/packages/addons/service/docker/patches/docker-001-use-addon-storage-location.patch b/packages/addons/service/docker/patches/docker-001-use-addon-storage-location.patch new file mode 100644 index 0000000000..cd97127c2d --- /dev/null +++ b/packages/addons/service/docker/patches/docker-001-use-addon-storage-location.patch @@ -0,0 +1,290 @@ +# Created with +# find . -name "*.go" -print | xargs sed -i 's/\/etc\/docker/\/storage\/.kodi\/userdata\/addon_data\/service.system.docker\/config/g' + +diff -Naur a/docker/daemon_unix.go b/docker/daemon_unix.go +--- a/docker/daemon_unix.go 2016-02-11 19:45:56.000000000 +0100 ++++ b/docker/daemon_unix.go 2016-02-19 00:28:50.662085695 +0100 +@@ -16,7 +16,7 @@ + _ "github.com/docker/docker/daemon/execdriver/native" + ) + +-const defaultDaemonConfigFile = "/etc/docker/daemon.json" ++const defaultDaemonConfigFile = "/storage/.kodi/userdata/addon_data/service.system.docker/config/daemon.json" + + func setPlatformServerConfig(serverConfig *apiserver.Config, daemonCfg *daemon.Config) *apiserver.Config { + serverConfig.SocketGroup = daemonCfg.SocketGroup +@@ -50,7 +50,7 @@ + } + + func getDaemonConfDir() string { +- return "/etc/docker" ++ return "/storage/.kodi/userdata/addon_data/service.system.docker/config" + } + + // setupConfigReloadTrap configures the USR2 signal to reload the configuration. +diff -Naur a/integration-cli/docker_cli_authz_unix_test.go b/integration-cli/docker_cli_authz_unix_test.go +--- a/integration-cli/docker_cli_authz_unix_test.go 2016-02-11 19:45:56.000000000 +0100 ++++ b/integration-cli/docker_cli_authz_unix_test.go 2016-02-19 00:28:50.642085661 +0100 +@@ -121,10 +121,10 @@ + } + }) + +- err := os.MkdirAll("/etc/docker/plugins", 0755) ++ err := os.MkdirAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", 0755) + c.Assert(err, checker.IsNil) + +- fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", testAuthZPlugin) ++ fileName := fmt.Sprintf("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/%s.spec", testAuthZPlugin) + err = ioutil.WriteFile(fileName, []byte(s.server.URL), 0644) + c.Assert(err, checker.IsNil) + } +@@ -163,7 +163,7 @@ + + s.server.Close() + +- err := os.RemoveAll("/etc/docker/plugins") ++ err := os.RemoveAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins") + c.Assert(err, checker.IsNil) + } + +diff -Naur a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go +--- a/integration-cli/docker_cli_daemon_test.go 2016-02-11 19:45:56.000000000 +0100 ++++ b/integration-cli/docker_cli_daemon_test.go 2016-02-19 00:28:50.636085651 +0100 +@@ -537,13 +537,13 @@ + + func (s *DockerDaemonSuite) TestDaemonKeyGeneration(c *check.C) { + // TODO: skip or update for Windows daemon +- os.Remove("/etc/docker/key.json") ++ os.Remove("/storage/.kodi/userdata/addon_data/service.system.docker/config/key.json") + if err := s.d.Start(); err != nil { + c.Fatalf("Could not start daemon: %v", err) + } + s.d.Stop() + +- k, err := libtrust.LoadKeyFile("/etc/docker/key.json") ++ k, err := libtrust.LoadKeyFile("/storage/.kodi/userdata/addon_data/service.system.docker/config/key.json") + if err != nil { + c.Fatalf("Error opening key file") + } +@@ -556,7 +556,7 @@ + + func (s *DockerDaemonSuite) TestDaemonKeyMigration(c *check.C) { + // TODO: skip or update for Windows daemon +- os.Remove("/etc/docker/key.json") ++ os.Remove("/storage/.kodi/userdata/addon_data/service.system.docker/config/key.json") + k1, err := libtrust.GenerateECP256PrivateKey() + if err != nil { + c.Fatalf("Error generating private key: %s", err) +@@ -573,7 +573,7 @@ + } + s.d.Stop() + +- k2, err := libtrust.LoadKeyFile("/etc/docker/key.json") ++ k2, err := libtrust.LoadKeyFile("/storage/.kodi/userdata/addon_data/service.system.docker/config/key.json") + if err != nil { + c.Fatalf("Error opening key file") + } +@@ -1337,7 +1337,7 @@ + Y string `json:"y"` + } + +- os.Remove("/etc/docker/key.json") ++ os.Remove("/storage/.kodi/userdata/addon_data/service.system.docker/config/key.json") + if err := s.d.Start(); err != nil { + c.Fatalf("Failed to start daemon: %v", err) + } +@@ -1347,7 +1347,7 @@ + } + + config := &Config{} +- bytes, err := ioutil.ReadFile("/etc/docker/key.json") ++ bytes, err := ioutil.ReadFile("/storage/.kodi/userdata/addon_data/service.system.docker/config/key.json") + if err != nil { + c.Fatalf("Error reading key.json file: %s", err) + } +@@ -1367,11 +1367,11 @@ + } + + // write back +- if err := ioutil.WriteFile("/etc/docker/key.json", newBytes, 0400); err != nil { ++ if err := ioutil.WriteFile("/storage/.kodi/userdata/addon_data/service.system.docker/config/key.json", newBytes, 0400); err != nil { + c.Fatalf("Error ioutil.WriteFile: %s", err) + } + +- defer os.Remove("/etc/docker/key.json") ++ defer os.Remove("/storage/.kodi/userdata/addon_data/service.system.docker/config/key.json") + + if err := s.d.Start(); err == nil { + c.Fatalf("It should not be successful to start daemon with wrong key: %v", err) +diff -Naur a/integration-cli/docker_cli_external_graphdriver_unix_test.go b/integration-cli/docker_cli_external_graphdriver_unix_test.go +--- a/integration-cli/docker_cli_external_graphdriver_unix_test.go 2016-02-11 19:45:56.000000000 +0100 ++++ b/integration-cli/docker_cli_external_graphdriver_unix_test.go 2016-02-19 00:28:50.632085644 +0100 +@@ -283,18 +283,18 @@ + respond(w, &graphDriverResponse{Size: size}) + }) + +- err = os.MkdirAll("/etc/docker/plugins", 0755) +- c.Assert(err, check.IsNil, check.Commentf("error creating /etc/docker/plugins")) ++ err = os.MkdirAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", 0755) ++ c.Assert(err, check.IsNil, check.Commentf("error creating /storage/.kodi/userdata/addon_data/service.system.docker/config/plugins")) + +- err = ioutil.WriteFile("/etc/docker/plugins/test-external-graph-driver.spec", []byte(s.server.URL), 0644) +- c.Assert(err, check.IsNil, check.Commentf("error writing to /etc/docker/plugins/test-external-graph-driver.spec")) ++ err = ioutil.WriteFile("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/test-external-graph-driver.spec", []byte(s.server.URL), 0644) ++ c.Assert(err, check.IsNil, check.Commentf("error writing to /storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/test-external-graph-driver.spec")) + } + + func (s *DockerExternalGraphdriverSuite) TearDownSuite(c *check.C) { + s.server.Close() + +- err := os.RemoveAll("/etc/docker/plugins") +- c.Assert(err, check.IsNil, check.Commentf("error removing /etc/docker/plugins")) ++ err := os.RemoveAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins") ++ c.Assert(err, check.IsNil, check.Commentf("error removing /storage/.kodi/userdata/addon_data/service.system.docker/config/plugins")) + } + + func (s *DockerExternalGraphdriverSuite) TestExternalGraphDriver(c *check.C) { +diff -Naur a/integration-cli/docker_cli_network_unix_test.go b/integration-cli/docker_cli_network_unix_test.go +--- a/integration-cli/docker_cli_network_unix_test.go 2016-02-11 19:45:56.000000000 +0100 ++++ b/integration-cli/docker_cli_network_unix_test.go 2016-02-19 00:28:50.629085639 +0100 +@@ -201,14 +201,14 @@ + } + }) + +- err := os.MkdirAll("/etc/docker/plugins", 0755) ++ err := os.MkdirAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", 0755) + c.Assert(err, checker.IsNil) + +- fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", netDrv) ++ fileName := fmt.Sprintf("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/%s.spec", netDrv) + err = ioutil.WriteFile(fileName, []byte(url), 0644) + c.Assert(err, checker.IsNil) + +- ipamFileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", ipamDrv) ++ ipamFileName := fmt.Sprintf("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/%s.spec", ipamDrv) + err = ioutil.WriteFile(ipamFileName, []byte(url), 0644) + c.Assert(err, checker.IsNil) + } +@@ -220,7 +220,7 @@ + + s.server.Close() + +- err := os.RemoveAll("/etc/docker/plugins") ++ err := os.RemoveAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins") + c.Assert(err, checker.IsNil) + } + +diff -Naur a/integration-cli/docker_cli_start_volume_driver_unix_test.go b/integration-cli/docker_cli_start_volume_driver_unix_test.go +--- a/integration-cli/docker_cli_start_volume_driver_unix_test.go 2016-02-11 19:45:56.000000000 +0100 ++++ b/integration-cli/docker_cli_start_volume_driver_unix_test.go 2016-02-19 00:28:50.651085676 +0100 +@@ -206,17 +206,17 @@ + send(w, nil) + }) + +- err := os.MkdirAll("/etc/docker/plugins", 0755) ++ err := os.MkdirAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", 0755) + c.Assert(err, checker.IsNil) + +- err = ioutil.WriteFile("/etc/docker/plugins/test-external-volume-driver.spec", []byte(s.server.URL), 0644) ++ err = ioutil.WriteFile("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/test-external-volume-driver.spec", []byte(s.server.URL), 0644) + c.Assert(err, checker.IsNil) + } + + func (s *DockerExternalVolumeSuite) TearDownSuite(c *check.C) { + s.server.Close() + +- err := os.RemoveAll("/etc/docker/plugins") ++ err := os.RemoveAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins") + c.Assert(err, checker.IsNil) + } + +@@ -301,7 +301,7 @@ + + // Make sure a request to use a down driver doesn't block other requests + func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverLookupNotBlocked(c *check.C) { +- specPath := "/etc/docker/plugins/down-driver.spec" ++ specPath := "/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/down-driver.spec" + err := ioutil.WriteFile(specPath, []byte("tcp://127.0.0.7:9999"), 0644) + c.Assert(err, check.IsNil) + defer os.RemoveAll(specPath) +@@ -340,7 +340,7 @@ + err := s.d.StartWithBusybox() + c.Assert(err, checker.IsNil) + +- specPath := "/etc/docker/plugins/test-external-volume-driver-retry.spec" ++ specPath := "/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/test-external-volume-driver-retry.spec" + os.RemoveAll(specPath) + defer os.RemoveAll(specPath) + +diff -Naur a/integration-cli/docker_cli_volume_driver_compat_unix_test.go b/integration-cli/docker_cli_volume_driver_compat_unix_test.go +--- a/integration-cli/docker_cli_volume_driver_compat_unix_test.go 2016-02-11 19:45:56.000000000 +0100 ++++ b/integration-cli/docker_cli_volume_driver_compat_unix_test.go 2016-02-19 00:28:50.646085667 +0100 +@@ -173,17 +173,17 @@ + send(w, nil) + }) + +- err := os.MkdirAll("/etc/docker/plugins", 0755) ++ err := os.MkdirAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", 0755) + c.Assert(err, checker.IsNil) + +- err = ioutil.WriteFile("/etc/docker/plugins/test-external-volume-driver.spec", []byte(s.server.URL), 0644) ++ err = ioutil.WriteFile("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins/test-external-volume-driver.spec", []byte(s.server.URL), 0644) + c.Assert(err, checker.IsNil) + } + + func (s *DockerExternalVolumeSuiteCompatV1_1) TearDownSuite(c *check.C) { + s.server.Close() + +- err := os.RemoveAll("/etc/docker/plugins") ++ err := os.RemoveAll("/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins") + c.Assert(err, checker.IsNil) + } + +diff -Naur a/pkg/plugins/discovery.go b/pkg/plugins/discovery.go +--- a/pkg/plugins/discovery.go 2016-02-11 19:45:56.000000000 +0100 ++++ b/pkg/plugins/discovery.go 2016-02-19 00:28:50.247084996 +0100 +@@ -15,7 +15,7 @@ + // ErrNotFound plugin not found + ErrNotFound = errors.New("plugin not found") + socketsPath = "/run/docker/plugins" +- specsPaths = []string{"/etc/docker/plugins", "/usr/lib/docker/plugins"} ++ specsPaths = []string{"/storage/.kodi/userdata/addon_data/service.system.docker/config/plugins", "/usr/lib/docker/plugins"} + ) + + // localRegistry defines a registry that is local (using unix socket). +diff -Naur a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go +--- a/pkg/plugins/plugins.go 2016-02-11 19:45:56.000000000 +0100 ++++ b/pkg/plugins/plugins.go 2016-02-19 00:28:50.263085023 +0100 +@@ -4,7 +4,7 @@ + // Docker discovers plugins by looking for them in the plugin directory whenever + // a user or container tries to use one by name. UNIX domain socket files must + // be located under /run/docker/plugins, whereas spec files can be located +-// either under /etc/docker/plugins or /usr/lib/docker/plugins. This is handled ++// either under /storage/.kodi/userdata/addon_data/service.system.docker/config/plugins or /usr/lib/docker/plugins. This is handled + // by the Registry interface, which lets you list all plugins or get a plugin by + // its name if it exists. + // +diff -Naur a/registry/config_unix.go b/registry/config_unix.go +--- a/registry/config_unix.go 2016-02-11 19:45:56.000000000 +0100 ++++ b/registry/config_unix.go 2016-02-19 00:28:50.742085829 +0100 +@@ -12,7 +12,7 @@ + + var ( + // CertsDir is the directory where certificates are stored +- CertsDir = "/etc/docker/certs.d" ++ CertsDir = "/storage/.kodi/userdata/addon_data/service.system.docker/config/certs.d" + ) + + // cleanPath is used to ensure that a directory name is valid on the target +diff -Naur a/registry/endpoint.go b/registry/endpoint.go +--- a/registry/endpoint.go 2016-02-11 19:45:56.000000000 +0100 ++++ b/registry/endpoint.go 2016-02-19 00:28:50.740085826 +0100 +@@ -73,7 +73,7 @@ + if endpoint.IsSecure { + // If registry is secure and HTTPS failed, show user the error and tell them about `--insecure-registry` + // in case that's what they need. DO NOT accept unknown CA certificates, and DO NOT fallback to HTTP. +- return fmt.Errorf("invalid registry endpoint %s: %v. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry %s` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/%s/ca.crt", endpoint, err, endpoint.URL.Host, endpoint.URL.Host) ++ return fmt.Errorf("invalid registry endpoint %s: %v. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry %s` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /storage/.kodi/userdata/addon_data/service.system.docker/config/certs.d/%s/ca.crt", endpoint, err, endpoint.URL.Host, endpoint.URL.Host) + } + + // If registry is insecure and HTTPS failed, fallback to HTTP. diff --git a/packages/addons/service/docker/source/bin/docker-config b/packages/addons/service/docker/source/bin/docker-config new file mode 100755 index 0000000000..da5002b070 --- /dev/null +++ b/packages/addons/service/docker/source/bin/docker-config @@ -0,0 +1,37 @@ +#!/bin/sh +################################################################################ +# This file is part of LibreELEC - http://www.libreelec.tv +# Copyright (C) 2009-2016 Lukas Rusak (lrusak@libreelec.tv) +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +ADDON_DIR="/storage/.kodi/addons/service.system.docker" +ADDON_HOME_DIR="/storage/.kodi/userdata/addon_data/service.system.docker" + +if [ ! -d "$ADDON_HOME_DIR/config" ]; then + mkdir -p $ADDON_HOME_DIR/config +fi + +if [ ! -f "$ADDON_HOME_DIR/config/docker.conf" ]; then + cp $ADDON_DIR/config/docker.conf $ADDON_HOME_DIR/config/docker.conf +fi + +if [ ! -d "$ADDON_HOME_DIR/docker" ]; then + mkdir -p $ADDON_HOME_DIR/docker +fi + +if [ ! -d /var/lib/docker ]; then + ln -sf $ADDON_HOME_DIR/docker /var/lib/docker +fi diff --git a/packages/addons/service/docker/source/config/docker.conf b/packages/addons/service/docker/source/config/docker.conf new file mode 100644 index 0000000000..36908b53d7 --- /dev/null +++ b/packages/addons/service/docker/source/config/docker.conf @@ -0,0 +1,2 @@ +DOCKER_DAEMON_OPTS="--graph=/storage/.kodi/userdata/addon_data/service.system.docker/docker" +DOCKER_STORAGE_OPTS="--storage-driver=overlay" diff --git a/packages/addons/service/docker/source/default.py b/packages/addons/service/docker/source/default.py new file mode 100644 index 0000000000..807ce9432b --- /dev/null +++ b/packages/addons/service/docker/source/default.py @@ -0,0 +1,103 @@ +################################################################################ +# This file is part of LibreELEC - http://www.libreelec.tv +# Copyright (C) 2009-2016 Lukas Rusak (lrusak@libreelec.tv) +# +# LibreELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# LibreELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LibreELEC. If not, see . +################################################################################ + +import os +import subprocess +import sys +import time +import xbmc +import xbmcaddon +import xbmcgui + +sys.path.append('/usr/share/kodi/addons/service.libreelec.settings') + +import oe + +__author__ = 'lrusak' +__addon__ = xbmcaddon.Addon() +__path__ = __addon__.getAddonInfo('path') +__service__ = __path__ + '/systemd/' + __addon__.getAddonInfo('id') + '.service' +__servicename__ = __addon__.getAddonInfo('id') + '.service' +__socket__ = __path__ + '/systemd/' + __addon__.getAddonInfo('id') + '.socket' +__socketname__ = __addon__.getAddonInfo('id') + '.socket' + +class Main(object): + + def __init__(self, *args, **kwargs): + + monitor = DockerMonitor(self) + + if not Docker().is_enabled(): + Docker().enable() + Docker().start() + + while not monitor.abortRequested(): + if monitor.waitForAbort(): + Docker().stop() + Docker().disable() + +class Docker(object): + + def enable(self): + self.execute('systemctl enable ' + __service__) + self.execute('systemctl enable ' + __socket__) + + def disable(self): + self.execute('systemctl disable ' + __servicename__) + self.execute('systemctl disable ' + __socketname__) + + def is_enabled(self): + if self.execute('systemctl is-enabled ' + __servicename__, get_result=1).strip('\n') == 'enabled': + return True + else: + return False + + def start(self): + self.execute('systemctl start ' + __servicename__) + + def stop(self): + self.execute('systemctl stop ' + __servicename__) + + def is_active(self): + if self.execute('systemctl is-active ' + __servicename__, get_result=1).strip('\n') == 'active': + return True + else: + return False + + def execute(self, command_line, get_result=0): + result = oe.execute(command_line, get_result=get_result) + if get_result: + return result + + def restart(self): + if self.is_active(): + self.stop() + self.start() + +class DockerMonitor(xbmc.Monitor): + + def __init__(self, *args, **kwargs): + xbmc.Monitor.__init__(self) + + def onSettingsChanged(self): + Docker().restart() + +if ( __name__ == "__main__" ): + Main() + + del DockerMonitor diff --git a/packages/addons/service/docker/source/examples/couchpotato.service b/packages/addons/service/docker/source/examples/couchpotato.service new file mode 100644 index 0000000000..3fd8b371f5 --- /dev/null +++ b/packages/addons/service/docker/source/examples/couchpotato.service @@ -0,0 +1,22 @@ +[Unit] +Description=%p container +Requires=service.system.docker.service +After=service.system.docker.service + +[Service] +Restart=always +RestartSec=10s +TimeoutStartSec=0 +ExecStartPre=-/bin/sh -c "mkdir -p /storage/%p/config /storage/%p/data" +ExecStart=/storage/.kodi/addons/service.system.docker/bin/docker run \ + --rm \ + --name=%p \ + --hostname=libreelec-%p \ + --volume=/storage/%p/config:/config \ + --volume=/storage/%p/data:/data \ + --publish=5050:5050 \ + timhaak/%p +ExecStop=/storage/.kodi/addons/service.system.docker/bin/docker stop %p + +[Install] +WantedBy=multi-user.target diff --git a/packages/addons/service/docker/source/examples/mysql.service b/packages/addons/service/docker/source/examples/mysql.service new file mode 100644 index 0000000000..77b0667ed1 --- /dev/null +++ b/packages/addons/service/docker/source/examples/mysql.service @@ -0,0 +1,26 @@ +[Unit] +Description=%p container +Requires=service.system.docker.service +After=service.system.docker.service +Befora=kodi.service + +[Service] +Restart=always +RestartSec=10s +TimeoutStartSec=0 +ExecStartPre=-/bin/sh -c "mkdir -p /storage/%p/config /storage/%p/data" +ExecStart=/storage/.kodi/addons/service.system.docker/bin/docker run \ + --rm \ + --name=%p \ + --hostname=libreelec-%p \ + --volume=/storage/%p/config/:/etc/mysql/conf.d \ + --volume=/storage/%p/data:/var/lib/mysql \ + --publish=3306:3306 \ + --env=MYSQL_ROOT_PASSWORD=libreelec \ + --env=MYSQL_USER=kodi \ + --env=MYSQL_PASSWORD=kodi \ + %p +ExecStop=/storage/.kodi/addons/service.system.docker/bin/docker stop %p + +[Install] +WantedBy=multi-user.target diff --git a/packages/addons/service/docker/source/examples/sabnzbd.service b/packages/addons/service/docker/source/examples/sabnzbd.service new file mode 100644 index 0000000000..e85e4da1b7 --- /dev/null +++ b/packages/addons/service/docker/source/examples/sabnzbd.service @@ -0,0 +1,22 @@ +[Unit] +Description=%p container +Requires=service.system.docker.service +After=service.system.docker.service + +[Service] +Restart=always +RestartSec=10s +TimeoutStartSec=0 +ExecStartPre=-/bin/sh -c "mkdir -p /storage/%p/config /storage/%p/data" +ExecStart=/storage/.kodi/addons/service.system.docker/bin/docker run \ + --rm \ + --name=%p \ + --hostname=libreelec-%p \ + --volume=/storage/%p/config:/config \ + --volume=/storage/%p/data:/data \ + --publish=8080:8080 \ + timhaak/%p +ExecStop=/storage/.kodi/addons/service.system.docker/bin/docker stop %p + +[Install] +WantedBy=multi-user.target diff --git a/packages/addons/service/docker/source/examples/sickbeard.service b/packages/addons/service/docker/source/examples/sickbeard.service new file mode 100644 index 0000000000..573342bb92 --- /dev/null +++ b/packages/addons/service/docker/source/examples/sickbeard.service @@ -0,0 +1,22 @@ +[Unit] +Description=%p container +Requires=service.system.docker.service +After=service.system.docker.service + +[Service] +Restart=always +RestartSec=10s +TimeoutStartSec=0 +ExecStartPre=-/bin/sh -c "mkdir -p /storage/%p/config /storage/%p/data" +ExecStart=/storage/.kodi/addons/service.system.docker/bin/docker run \ + --rm \ + --name=%p \ + --hostname=libreelec-%p \ + --volume=/storage/%p/config:/config \ + --volume=/storage/%p/data:/data \ + --publish=8081:8081 \ + timhaak/%p +ExecStop=/storage/.kodi/addons/service.system.docker/bin/docker stop %p + +[Install] +WantedBy=multi-user.target diff --git a/packages/addons/service/docker/source/examples/transmission.service b/packages/addons/service/docker/source/examples/transmission.service new file mode 100644 index 0000000000..7a248c6934 --- /dev/null +++ b/packages/addons/service/docker/source/examples/transmission.service @@ -0,0 +1,24 @@ +[Unit] +Description=%p container +Requires=service.system.docker.service +After=service.system.docker.service + +[Service] +Restart=always +RestartSec=10s +TimeoutStartSec=0 +ExecStartPre=-/bin/sh -c "mkdir -p /storage/%p/watch /storage/%p/downloads /storage/%p/incomplete /storage/%p/config" +ExecStart=/storage/.kodi/addons/service.system.docker/bin/docker run \ + --rm \ + --name=%p \ + --hostname=libreelec-%p \ + --volume=/storage/%p/watch:/watch \ + --volume=/storage/%p/downloads:/downloads \ + --volume=/storage/%p/incomplete:/incomplete \ + --volume=/storage/%p/config:/config \ + --publish=9091:9091 \ + timhaak/%p +ExecStop=/storage/.kodi/addons/service.system.docker/bin/docker stop %p + +[Install] +WantedBy=multi-user.target diff --git a/packages/addons/service/docker/source/examples/var-lib-docker.mount b/packages/addons/service/docker/source/examples/var-lib-docker.mount new file mode 100644 index 0000000000..6744e125c3 --- /dev/null +++ b/packages/addons/service/docker/source/examples/var-lib-docker.mount @@ -0,0 +1,14 @@ +[Unit] +Description=Docker loopback mount +Requires=local-fs.target +Before=service.system.docker.service + +[Mount] +What=/storage/btrfs-loop.img +Where=/var/lib/docker + +Options=loop,compress=lzo +Type=btrfs + +[Install] +WantedBy=multi-user.target diff --git a/packages/addons/service/docker/source/systemd/service.system.docker.service b/packages/addons/service/docker/source/systemd/service.system.docker.service new file mode 100644 index 0000000000..0a2d5add32 --- /dev/null +++ b/packages/addons/service/docker/source/systemd/service.system.docker.service @@ -0,0 +1,19 @@ +[Unit] +Description=Docker Application Container Engine +Documentation=https://docs.docker.com +After=network.target docker.socket +Requires=docker.socket + +[Service] +Type=notify +ExecStartPre=/storage/.kodi/addons/service.system.docker/bin/docker-config +EnvironmentFile=-/storage/.kodi/userdata/addon_data/service.system.docker/config/docker.conf +ExecStart=/storage/.kodi/addons/service.system.docker/bin/docker daemon -H fd:// $DOCKER_DAEMON_OPTS $DOCKER_STORAGE_OPTS +MountFlags=slave +LimitNOFILE=1048576 +LimitNPROC=1048576 +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target +Alias=docker.service diff --git a/packages/addons/service/docker/source/systemd/service.system.docker.socket b/packages/addons/service/docker/source/systemd/service.system.docker.socket new file mode 100644 index 0000000000..578b38bc98 --- /dev/null +++ b/packages/addons/service/docker/source/systemd/service.system.docker.socket @@ -0,0 +1,13 @@ +[Unit] +Description=Docker Socket for the API +PartOf=docker.service + +[Socket] +ListenStream=/var/run/docker.sock +SocketMode=0660 +SocketUser=root +SocketGroup=root + +[Install] +WantedBy=sockets.target +Alias=docker.socket