diff --git a/.gitmodules b/.gitmodules index ec7a2f8fd..e69de29bb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "isolate"] - path = isolate - url = https://github.com/ioi/isolate.git diff --git a/docs/Installation.rst b/docs/Installation.rst index ed8d5f8d8..fc886c35e 100644 --- a/docs/Installation.rst +++ b/docs/Installation.rst @@ -152,11 +152,19 @@ Download :gh_download:`CMS` |release| from GitHub as an archive, then extract it In order to run CMS there are some preparation steps to run (like installing the sandbox, compiling localization files, creating the ``cmsuser``, and so on). You can either do all these steps by hand or you can run the following command: +.. warning:: + In previous versions, ``prerequisites.py`` also installed ``isolate``. + This is no longer the case, as ``isolate`` is now packaged for many distributions, and users may choose different versions of ``isolate`` depending on which version of ``cgroups`` they are using. + + Note however that ``cms`` expects to be able to run ``isolate`` without root, which not all packages provide. + +.. FIXME -- We should consider making the path to 'isolate' configurable, allowing users to create custom wrappers for e.g. setuid or sudo. + .. sourcecode:: bash sudo python3 prerequisites.py install -.. FIXME -- The following part probably does not need to be mentioned. Moreover, it would be better if isolate was just a dependency (like postgresql) to be installed separately, with its own group (e.g. 'isolate' instead of 'cmsuser'). The 'cmsuser' group could just become deprected, at that point. +.. FIXME -- The following part probably does not need to be mentioned. Moreover, since we now treat ``isolate`` as a dependency to be installed externally (and likely with its own group), we could deprecate the `cmsuser` group. This script will add you to the ``cmsuser`` group if you answer ``Y`` when asked. If you want to handle your groups by yourself, answer ``N`` and then run: diff --git a/isolate b/isolate deleted file mode 160000 index e40c13185..000000000 --- a/isolate +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e40c13185c8a10e4a5fd9ebd81c296ff1fdc69a6 diff --git a/prerequisites.py b/prerequisites.py index 0968b50a2..ab5cbce20 100755 --- a/prerequisites.py +++ b/prerequisites.py @@ -50,6 +50,8 @@ # Do not even try to install configuration files (i.e., copying the # samples) when installing. NO_CONF = False +# Do not check isolate availability +NO_CHECK_ISOLATE = False # The user and group that CMS will be run as: will be created and will # receive the correct permissions to access isolate, the configuration # file and the system directories. @@ -187,56 +189,28 @@ def get_real_user(): return name +def check_isolate(gr_name): + print("===== Verifying isolate availability") -def build_isolate(): - """This function compiles the isolate sandbox. - - """ - assert_not_root() - - print("===== Compiling isolate") - # We make only the executable isolate, otherwise the tool a2x - # is needed and we have to add more compilation dependencies. - subprocess.check_call(["make", "-C", "isolate", "isolate"]) - - -def install_isolate(): - """This function installs the isolate sandbox. - - """ - assert_root() - root = pwd.getpwnam("root") - try: - cmsuser_grp = grp.getgrgid(pwd.getpwnam(CMSUSER).pw_gid) - except: - print("[Error] The user %s doesn't exist yet" % CMSUSER) - print("[Error] You need to run the install command at least once") - exit(1) - - # Check if build_isolate() has been called - if not os.path.exists(os.path.join("isolate", "isolate")): - print("[Error] You must run the build_isolate command first") - exit(1) - - print("===== Copying isolate to /usr/local/bin/") - makedir(os.path.join(USR_ROOT, "bin"), root, 0o755) - copyfile(os.path.join(".", "isolate", "isolate"), - os.path.join(USR_ROOT, "bin", "isolate"), - root, 0o4750, group=cmsuser_grp) - - print("===== Copying isolate config to /usr/local/etc/") - makedir(os.path.join(USR_ROOT, "etc"), root, 0o755) - copyfile(os.path.join(".", "isolate", "default.cf"), - os.path.join(USR_ROOT, "etc", "isolate"), - root, 0o640, group=cmsuser_grp) - - -def build(): - """This function builds all the prerequisites by calling: - - build_isolate + isolate_test_run = subprocess.run(["sudo", "-E", "-u", CMSUSER, "isolate --cg --init"], stdout = subprocess.PIPE, stderr = subprocess.STDOUT, text=True) + if isolate_test_run.returncode == 0: + subprocess.run(["sudo", "-E", "-u", CMSUSER, "isolate --cg --cleanup"]) + else: + print(''' +########################################################################### +### ### +### 'isolate' failed with the following error: ### +--------------------------------------------------------------------------- + ''') + print(isolate_test_run.stdout) + print(''' +--------------------------------------------------------------------------- +### Note that cms expects users in the %s group to be able to ### +### be able to run 'isolate' without sudo. ### +### ### +########################################################################### + ''' % gr_name) - """ - build_isolate() def install_conf(): @@ -291,15 +265,9 @@ def install(): root_pw = pwd.getpwnam("root") - if real_user == "root": - # Run build() command as root - build() - else: - # Run build() command as not root - subprocess.check_call(["sudo", "-E", "-u", real_user, - sys.executable, sys.argv[0], "build"]) - - install_isolate() + # Check if isolate is installed, and executable as CMSUSER. + # Otherwise, print a warning. + check_isolate(cmsuser_gr.gr_name) # We set permissions for each manually installed files, so we want # max liberty to change them. @@ -434,6 +402,10 @@ def uninstall(): parser.add_argument( "--no-conf", action="store_true", help="Don't install configuration files") + parser.add_argument( + "--no-check-isolate", action="store_true", + help="Do not check if isolate is available. (Note: cms will not be able to run properly without isolate)" + ) parser.add_argument( "--as-root", action="store_true", help="(DON'T USE) Allow running non-root commands as root") @@ -444,15 +416,6 @@ def uninstall(): subparsers = parser.add_subparsers(metavar="command", help="Subcommand to run") - subparsers.add_parser("build_isolate", - help="Build \"isolate\" sandbox") \ - .set_defaults(func=build_isolate) - subparsers.add_parser("build", - help="Build everything") \ - .set_defaults(func=build) - subparsers.add_parser("install_isolate", - help="Install \"isolate\" sandbox (requires root)") \ - .set_defaults(func=install_isolate) subparsers.add_parser("install", help="Install everything (requires root)") \ .set_defaults(func=install) @@ -466,6 +429,7 @@ def uninstall(): NO_CONF = args.no_conf AS_ROOT = args.as_root CMSUSER = args.cmsuser + NO_CHECK_ISOLATE = args.no_check_isolate if not hasattr(args, "func"): parser.error("Please specify a command to run. "