Best practice for a cifs mount

Hello,

I am on a self-hosted GitLab instance. I have a separate project-runner for my project.

I want to use the CI/CD pipeline to put files on a file server (with cifs).
My .gitlab.yml file currently looks like this.

mount:
    stage: build
    image: ubuntu:20.04
    script:
	    - apt install cifs-utils
        - mount -t cifs -o credentials=$CREDENTIALS //<server>/sharefolder /mnt/mountpoint

The error message I currently get is this:

Unable to apply new capability set.

I have seen a number of answers on the internet, but none that really helped me. Especially as some of the solutions also tend to advise against it.
I have already tried the commands in my .gitlab-ci.yml in a VM, where it was no problem.
Hope someone can help me.

Have you checked this answer on Stackoverflow: Azure FileShare on Docker returns Unable to apply new capability set - Stack Overflow ?

You need to configure your Gitlab Runner to give the extra capabilities the mount command needs with the container it runs in, otherwise it won’t work.

-cap-add=SYS_ADMIN --cap-add=DAC_READ_SEARCH

See the [runners.docker] section and find the cap_add parameter there (“Add additional Linux capabilities to the container.”).

config.toml:

[runners.docker]
  cap_add = ["SYS_ADMIN", "DAC_READ_SEARCH"]

The merge request is back from Feb 2016:
Add support for cap_add, cap_drop, and devices in Docker executor
and you can find more examples there.

I saw that, but couldn’t do much with it. With your answer together, I understand it more. I will try it tomorrow. Thank you!

Otherwise, I have currently built a workaround with Python. I can use the smbprotocol lib to authenticate myself on the file server without any problems and put files on it.

That sounds reasonable with the pyhton library. Would be nice you could share the example code here, as I think the capabilities may be over the top (also it requires configuring the runner, so good to have some more options). @botkero

I can gladly share my solution.

First my CI/CD job. Nothing special here. Install the library and start the script.
gitlab-ci.yml:

my_file_transfer_job:
    image: python:3.11.1
    script:
        - pip install smbprotocol
        - python3 file_transfer.py

file_transfer.py:

from os import environ
import smbclient
from pathlib import Path

def main() -> None:
    # auth with SMB/CIFS
    user = environ.get("SMB_USER")
    password = environ.get("SMB_PASSWORD")
    smbclient.ClientConfig(username=user, password=password)
    
    # basepath
    server = environ.get("SMB_SERVER_NAME") # e.g. example-server
    share = "sharefolder"
    basepath = Path(r"\\{}".format(server)).joinpath(share)
    
    # check whether folder exist
    if "folder" in smbclient.listdir(basepath):
        folder_path = basepath.joinpath("folder")
        smbclient.mkdir(folder_path)
        file_to_copy = Path("test.txt")
		
        # copy file to file server
		# Can't use smbclient.copyfile because that only works within the server. 
        with open(file_to_copy, "r", encoding="utf-8") as src_file:
            data = src_file.read()
            with smbclient.open_file(version_folder.joinpath(file_to_copy), "w", encoding="utf-8") as dest_file:
                dest_file.write(data)

if __name__ == "__main__":
    main()

A few words about this. I have stored the credentials in CI variables. They then work like environment variables when you need them. Otherwise, I copy the content of a text.txt into the fileserver, nothing special.

1 Like