microsoft / azure-pipelines-agent

Azure Pipelines Agent 🚀
MIT License
1.72k stars 866 forks source link

[Question]: Why does the Initialize Containers step always mount the workspace in the container? #5005

Open BasJ93 opened 1 week ago

BasJ93 commented 1 week ago

Describe your question

As the use of running a stage within a container is described as a way to always have a clean environment, it feels weird that multiple host folders are automatically mounted in the container. I would expect to just get a running container, and still need to do the checkout step within the container for example.

Based on this snippet of Agent code, it would not appear so:

if (container.ImageOS != PlatformUtil.OS.Windows)
            {
                string workspace = executionContext.Variables.Get(Constants.Variables.Pipeline.Workspace);
                workspace = container.TranslateContainerPathForImageOS(PlatformUtil.HostOS, container.TranslateToContainerPath(workspace));
                string mountWorkspace = container.TranslateToHostPath(workspace);
                executionContext.Debug($"Workspace: {workspace}");
                executionContext.Debug($"Mount Workspace: {mountWorkspace}");
                container.MountVolumes.Add(new MountVolume(mountWorkspace, workspace, readOnly: container.isReadOnlyVolume(Constants.DefaultContainerMounts.Work)));

                container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Temp), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Temp))));
                container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Tasks), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Tasks)),
                    readOnly: container.isReadOnlyVolume(Constants.DefaultContainerMounts.Tasks)));
            }

Currently, this is problematic for our application of containerized stages, as the stage suddenly contains test dlls (and application code) from a different stage, which we do not want.

Have we missed a knob/argument/feature flag that allows us to disable this behavior?

Versions

Azure Devops 3.243.1 on Ubuntu 20.04 LTS

Environment type (Please select at least one enviroment where you face this issue)

Azure DevOps Server type

dev.azure.com (formerly visualstudio.com)

Operation system

Ubuntu 20.04

Version controll system

Git with external repo

Azure DevOps Server Version (if applicable)

3.243.1

ivanduplenskikh commented 1 week ago

@BasJ93, сould you please provide more details on your request? Are you asking for a way to configure a stage that operates within a container without needing a _work directory for your source files?

I recommend implementing a workaround to remove unnecessary sources at the end of your stage, or you could use the checkout task with the option clean: true.

BasJ93 commented 1 week ago

Are you asking for a way to configure a stage that operates within a container without needing a _work directory for your source files?

No, I'm looking for a way where the _work directory of the host is not mapped in to the container. Allowing me to just download an artifact to use within the container.

Our use case (that we wish to get working) is running unit tests in an isolated container environment, so that we run a specific set of tests that require data placed in our custom image.

Due to the workspace being mapped in to the container, we end up running more tests than we need, because the other tests in the project are also detected. We would very much like to not have to clean the workspace of the host, as our repository is quite large and would then require a full clone again.

In conclusion: is it possible to configure the agent to not mount the _work directory in to the container, and just create an empty _w within the container to place data from artifacts?

@ivanduplenskikh Any comment?

ivanduplenskikh commented 6 days ago

@BasJ93, apologies for the delay in getting back to you.

I have been gathering the necessary details related to your question.

The _work directory's mapping is by design behavior. You can refer to this documentation https://github.com/microsoft/azure-pipelines-agent/blob/master/docs/jobdirectories.md for a better understanding of why the _work directory is needed to keep working files and folders.

Currently, there are no mechanisms in place to prevent this folder from being mounted in a container.

However, you might find a workaround by either deleting unnecessary files in a prior step or by setting up a separate agent dedicated to testing. This agent could download your artifact and conduct the required tests in an isolated environment.