can I use several usernames in maven settings.xml file? - maven

our Nexus repository is configured to use repository-target permissions:
user1 can deploy to com.company.group1,
user2 can deploy to com.company.group2, etc.
can we have both user1 and user2 credentials for the same Maven repository in .m2/settings.xml file? will Maven try them both if permission is denied for one of them?

I use properties in distributionManagement, like-
<distributionManagement>
<repository>
<id>releases</id>
<url>${url.releases}</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>${url.snapshots}</url>
</snapshotRepository>
<site>
<id>site</id>
<url>${url.site}</url>
</site>
</distributionManagement>
My settings.xml has profiles that define these properties for target repositories. The <id> are matched with the <server> in the settings.xml, so you could use different <id> for different username/password/repository combination. In settings.xml, setup <activeProfiles> to the default profile you need for your deployment. When you need to switch to a different profile, you can do so on the command line.

You could e.g. use different profiles for each user and set user name and password as properties in those profiles. Then you could activate the profile depending on what user you want to work as at the moment. You could also set one of the profiles to be active by default so that you don't have to always use a profile name in your invocations.
Another way to do it would be to have separate settings.xml files for the users and specify the desired one with the -s flag for the maven invocation.

You can't mix credentials in the same settings.xml file, as far as I know; seems this would be a large security hole. Each user should have his own login on your build machine; then each person has his own .m2/settings.xml and .m2/settings-security.xml files (you need the latter to encrypt passwords). Each user adds <server> entries with ids matching the ids in the <distributionManagement> section for the projects being deployed.

Related

How to set global maven distrubution management settings?

I want to avoid putting this part in pom.xml of every project distributed the same way
<distributionManagement>
<repository>
<id>my-id</id>
<name>My deployed artifacts</name>
<url>https://organization.xxx/maven/</url>
</repository>
</distributionManagement>
How to set it globally via maven command or editing setting file?
Cannot be done in settings.xml.
What you can do:
Use a company parent POM that specifies the distributionManagement.
Set a property in the settings.xml and use it in distributionManagement.
Use -DaltDeploymentRepository=... on command line for the build. See also https://maven.apache.org/plugins/maven-deploy-plugin/deploy-mojo.html#altDeploymentRepository

Maven does not reference the settings.xml for a repository when deploying

I am trying to configure the deploy step in a Maven 3.0.4 POM using the <distributionManagement> tag. From XSD for POMs (line 1389), it suggests that merely providing the id should allow Maven too look up the corresponding values from the settings.xml file. I have the desired server listed (which is configured correctly since I can pull dependencies from it and see it mentioned when running in -X debug mode: [DEBUG] Repositories (dependencies): [archiva.snapshots (http://snap-mvnrepo.initech.com/archiva/repository/snapshots, releases+snapshots)]) in the settings.xml. However, when I just provide the <id> in my POM and try to deploy, I get an error that Maven is missing the URL for the repository, but when I explicitly provide the <url> the deploy works.
Does anyone know what I should do to get it working by id only? I don't want to hard code the URL.
DISCLAIMERS: Typos are likely the result of anonymization, but it is possible that they are "real" so feel free to point away at any.
About the <id> child tag of <repository> from the XSD for POMs (line 1389):
A unique identifier for a repository. This is used to match the repository to configuration in the settings.xml file, for example.
From my settings.xml:
<profile>
<id>archiva_dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>archiva.snapshots</id>
<name>Initech Internal Snapshot Repository</name>
<url>http://snap-mvnrepo.initech.com/archiva/repository/snapshots</url>
</repository>
</repositories>
</profile>
From my (failing) pom.xml:
<distributionManagement>
<repository>
<id>archiva.snapshots</id>
<!--
<name>Initech Internal Snapshot Repository</name>
<url>http://snap-mvnrepo.initech.com/archiva/repository/snapshots</url>
-->
</repository>
</distributionManagement>
The error:
Caused by: java.lang.IllegalStateException: Failed to create release distribution repository for com.initech.ws:initechws:pom:1.0-SNAPSHOT
at org.apache.maven.project.MavenProject.getReleaseArtifactRepository(MavenProject.java:1853)
at org.apache.maven.project.MavenProject.getDistributionManagementArtifactRepository(MavenProject.java:1377)
at org.apache.maven.plugin.deploy.DeployMojo.getDeploymentRepository(DeployMojo.java:227)
at org.apache.maven.plugin.deploy.DeployMojo.execute(DeployMojo.java:118)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
... 20 more
Caused by: org.apache.maven.artifact.InvalidRepositoryException: URL missing for repository archiva.snapshots
at org.apache.maven.repository.legacy.LegacyRepositorySystem.buildArtifactRepository(LegacyRepositorySystem.java:775)
at org.apache.maven.project.MavenProject.getReleaseArtifactRepository(MavenProject.java:1843)
... 24 more
The /project/distributionManagement/id value defines the /settings/servers/server/id to match against in order to identify the credentials to use when connecting to the url specified by /project/distributionManagement/url
Because the URL for deployment is very often different from the URL for read access, and the same credentials may apply to multiple URLs, there is no looking up of /project/repositories/repository or /project/pluginRepositories/pluginRepository.
The short answer is thus that you must specify /project/distributionManagement/url in order to be able to deploy, and if you need credentials in order to deploy to that URL you need to specify /project/distributionManagement/id and ensure that the matching credentials exist in your settings.xml
How could we update the documentation to make the above clearer and prevent future users from becoming confused in the manner you have been?
Update
The modello toolchain is generating the XSL with only some of the sentences, so
A unique identifier for a repository. This is used to match the repository to configuration in the settings.xml file, for example.
Is actually
A unique identifier for a repository. This is used to match the repository
to configuration in the settings.xml file, for example.
Furthermore, the identifier is used during POM inheritance and profile
injection to detect repositories that should be merged.
Source
Finally in order to fully make sense of the sentence, you need to be aware that the settings.xml file is just the source of settings when Maven is invoked from the command line. Maven Embedder may actually mean that the settings provided to Maven come from some other source entirely (think, e.g. from the configuration database of Eclipse or another IDE) which is the reason for some of the fun in MRELEASE-577.
A better way to read the first sentence might be
A unique identifier for a repository. This is used to match the repository to configuration, for example in the settings.xml file.
But if you can suggest something even better I will update the docs accordingly

Adding maven nexus repo to my pom.xml

I have installed nexus on my local machine. I want my pom file to point to this repo. How can I add my custom repository to my pom.xml file?
From Maven - Settings Reference
The repositories for download and deployment are defined by the repositories and distributionManagement elements of the POM. However, certain settings such as username and password should not be distributed along with the pom.xml. This type of information should exist on the build server in the settings.xml.
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
...
<servers>
<server>
<id>server001</id>
<username>my_login</username>
<password>my_password</password>
<privateKey>${user.home}/.ssh/id_dsa</privateKey>
<passphrase>some_passphrase</passphrase>
<filePermissions>664</filePermissions>
<directoryPermissions>775</directoryPermissions>
<configuration></configuration>
</server>
</servers>
...
</settings>
id: This is the ID of the server (not of the user to login as) that matches the id element of the repository/mirror that Maven tries to connect to.
username, password: These elements appear as a pair denoting the login and password required to authenticate to this server.
privateKey, passphrase: Like the previous two elements, this pair specifies a path to a private key (default is ${user.home}/.ssh/id_dsa) and a passphrase, if required. The passphrase and password elements may be externalized in the future, but for now they must be set plain-text in the settings.xml file.
filePermissions, directoryPermissions: When a repository file or directory is created on deployment, these are the permissions to use. The legal values of each is a three digit number corrosponding to *nix file permissions, ie. 664, or 775.
Note: If you use a private key to login to the server, make sure you omit the element. Otherwise, the key will be ignored.
All you should need is the id, username and password
The id and URL should be defined in your pom.xml like this:
<repositories>
...
<repository>
<id>acme-nexus-releases</id>
<name>acme nexus</name>
<url>https://nexus.acme.net/content/repositories/releases</url>
</repository>
...
</repositories>
If you need a username and password to your server, you should encrypt it.
Maven Password Encryption
First of all I can highly recommend reading the Nexus book. It will explain the benefits of using a Maven repository manager.
There is a section on how to configure your Maven build to use Nexus:
http://www.sonatype.com/books/nexus-book/reference/config.html
This leads me to question why you altering your POM file? I suspect what you really want to do is setup Nexus as a remote repository mirror. This is done in your Maven settings file.
The following tells Maven use Nexus as your default repository (Instead of Maven Central)
<settings>
..
..
<mirrors>
<mirror>
<id>nexus</id>
<url>http://localhost:8081/nexus/content/groups/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
This is desired behaviour since your Nexus repository is configured to cache artifacts retrieved from Central (which is good for build performance).
Note:
The "public" repository group could include other repositories proxied by your Nexus instance (Not just Maven Central). You probabily want this behaviour, as it centralizes all repository management. It just makes your build less portable for people outside of your organization.
It seems the answers here do not support an enterprise use case where a Nexus server has multiple users and has project-based isolation (protection) based on user id ALONG with using an automated build (CI) system like Jenkins. You would not be able to create a settings.xml file to satisfy the different user ids needed for different projects. I am not sure how to solve this, except by opening Nexus up to anonymous access for reading repositories, unless the projects could store a project-specific generic user id in their pom.xml.
From the Apache Maven site
<project>
...
<repositories>
<repository>
<id>my-internal-site</id>
<url>http://myserver/repo</url>
</repository>
</repositories>
...
</project>
"The repositories for download and deployment are defined by the repositories and distributionManagement elements of the POM. However, certain settings such as username and password should not be distributed along with the pom.xml. This type of information should exist on the build server in the settings.xml." - Apache Maven site - settings reference
<servers>
<server>
<id>server001</id>
<username>my_login</username>
<password>my_password</password>
<privateKey>${user.home}/.ssh/id_dsa</privateKey>
<passphrase>some_passphrase</passphrase>
<filePermissions>664</filePermissions>
<directoryPermissions>775</directoryPermissions>
<configuration></configuration>
</server>
</servers>
If you don't want or you cannot modify the settings.xml file, you can create a new one at the root of your project, and call maven passing it as a parameter with the -s argument:
$ mvn COMMAND ... -s settings.xml
From maven setting reference, you can not put your username/password in a pom.xml
The repositories for download and deployment are defined by the repositories and distributionManagement elements of the POM. However, certain settings such as username and password should not be distributed along with the pom.xml. This type of information should exist on the build server in the settings.xml.
You can first add a repository in your pom and then add the username/password in the $MAVEN_HOME/conf/settings.xml:
<servers>
<server>
<id>my-internal-site</id>
<username>yourUsername</username>
<password>yourPassword</password>
</server>
</servers>

Infrastructure - Maven + Nexus

I've installed a sonatype nexus to be my maven repo. The nexus instalation is using the Active Directory to authenticate users, and the annonymous login is off.
Every user that uploads an artifact to my repo must be identifyed with a unique username, thus the AD integration.
The regular way to use this structure is to set in the POM.xml the Distribution Managemente tag so the artifact is sent to nexus
<distributionManagement>
...
<repository>
<id>deploymentRepo</id>
<name>Internal Releases</name>
<url>http://nexusserver:8081/nexus/content/repositories/releases</url>
</repository>
...
</distributionManagement>
In the local repo settings (~/.m2/settings.xml) add the username/password combo to login into nexus
<server>
<id>deploymentRepo</id>
<username>deployment</username>
<password>deployment123</password>
</server>
It's working great for me, but what I'm trying to achieve is to somehow do the auth in nexus without having to put the user password in the local repo. Is it possible?
What are you trying to achieve: not to store password as plain text or for user having to pass password every time it runs maven deploy command?
Password could be stored in encrypted form, as described here
Or you could try to pass password on command line like below, but I haven't tried that:
mnv -Dpassword=deployment123 deploy
Nexus 2.1 is due to be released in June and we've built a new feature to support secure authentication without requiring a clear text password in the settings.xml.

maven distributionManagement outside the pom

Anyway I can move the distributionManagement part outside the pom
I don't like the idea that my pom.xml contains server location,
Is it possible to move this or server name to settings.xml?
Thanks
<distributionManagement>
<repository>
<id>archiva</id>
<name>archiva Repo</name>
<url>http://ca.server:8080/archiva/repository/snapshots/</url>
</repository>
<snapshotRepository>
<uniqueVersion>false</uniqueVersion>
<id>archiva</id>
<name>archiva Repo</name>
<url>http://ca.server:8080/archiva/repository/snapshots/</url>
</snapshotRepository>
</distributionManagement>
The best idea for this is to put such information into a parent POM (company pom) and use this instead of the settings.xml cause any body who wan't to build needs to change the settings.xml.
Short answer: Yes, you can.
Longer answer: I like the idea too, because I could imagine that the application will be built and distributed on different servers. So I like the following:
Define in the POM the dependencies to other libraries and plugins.
Define in your Maven installation configuration (so it is dependent on the installation, not on the user using that installation) what you have sketched out in your question.
Normally, you need a user-id and password to distribute in a Maven repository, and this is the (only) contents of it:
<settings>
<servers>
<server>
<id>archiva</id>
<username>XXadmin-user-nameXX</username>
<password>XXadmin-passwordXX</password>
</server>
</servers>
</settings>
This should only be on the build server configured by the build manager and not known by everyone. The only thing you have to ensure is that the IDs are the same in both files.

Resources