नेवेन के बिना, नेक्सस पर कलाकृतियों को अपलोड करें


102

मेरे पास एक गैर-जावा परियोजना है जो एक संस्करण निर्मित कलाकृति का उत्पादन करती है, और मैं इसे एक नेक्सस रिपॉजिटरी में अपलोड करना चाहता हूं। क्योंकि प्रोजेक्ट जावा नहीं है, यह बिल्ड के लिए मावेन का उपयोग नहीं करता है। और मैं बल्कि नेक्सस में फ़ाइलों को प्राप्त करने के लिए मावेन / पीओएम फाइलों को पेश नहीं करूंगा।

Nexus REST API पर ब्लॉग के लिंक सभी साइन-इन दीवार पर समाप्त होते हैं, जिसमें कोई "उपयोगकर्ता नहीं" लिंक होता है जिसे मैं देख सकता हूं।

तो, मावेन के बिना नेक्सस रिपॉजिटरी में कलाकृतियों को अपलोड करने का सबसे अच्छा (या कोई भी उचित) तरीका क्या है? "बैश + कर्ल" बहुत अच्छा होगा, या यहां तक ​​कि पायथन स्क्रिप्ट भी।


ध्यान दें, सुनिश्चित करें कि आपके पास उचित सर्वर और ऑर्किड परिभाषित के साथ ~ / .m2 में एक सेटिंग है। xml।
एडम वंडेनबर्ग

जवाबों:


98

क्या आपने फ़ाइलों को अपलोड करने के लिए मावेन कमांड-लाइन का उपयोग करने पर विचार किया है?

mvn deploy:deploy-file \
    -Durl=$REPO_URL \
    -DrepositoryId=$REPO_ID \
    -DgroupId=org.myorg \
    -DartifactId=myproj \
    -Dversion=1.2.3  \
    -Dpackaging=zip \
    -Dfile=myproj.zip

यह स्वचालित रूप से कलाकृतियों के लिए मावेन पोम उत्पन्न करेगा।

अपडेट करें

निम्नलिखित सोनाटाइप लेख में कहा गया है कि "परिनियोजित-फाइल" मावेन प्लगइन सबसे आसान समाधान है, लेकिन यह दही के साथ कुछ उदाहरण भी प्रदान करता है:

https://support.sonatype.com/entries/22189106-How-can-I-programatically-upload-an-artifact-into-Nexus-


यदि केवल यह हमें इस ज़िप के भीतर से फ़ाइलों को सीधे डाउनलोड करने की अनुमति देगा, लेकिन ऐसा लगता है कि यदि आप इसे इस तरह अपलोड करते हैं तो यह संभव नहीं है।
सोरिन

@ सोरिन मावेन का उपयोग करके एक ज़िप में फ़ाइलों को डाउनलोड करना संभव नहीं है। यह एक असामान्य आवश्यकता है और एकमात्र निर्भरता प्रबंधक जो मुझे पता है कि यह कर सकता है वह आइवी है (और यह सरल नहीं है) निम्न उदाहरण देखें: stackoverflow.com/questions/3445696/…
मार्क O'Connor

मैंने इसे सभी सरल बनाने के लिए नेक्सस स्थापित किया, लेकिन यह क्या है? यह क्या है? अगर मेरे पास इसकी निर्भरता के ज्ञान के बिना कुछ घर का जार है? मेरी आईडीई गुम * .pom के बारे में शिकायत करती रहती है। मुझे उम्मीद थी कि नेक्सस पहले से ही मेरे लिए है, लेकिन NOOOOO श ...
vintproykt

66

कर्ल का उपयोग करना:

curl -v \
    -F "r=releases" \
    -F "g=com.acme.widgets" \
    -F "a=widget" \
    -F "v=0.1-1" \
    -F "p=tar.gz" \
    -F "file=@./widget-0.1-1.tar.gz" \
    -u myuser:mypassword \
    http://localhost:8081/nexus/service/local/artifact/maven/content

आप देख सकते हैं कि मापदंडों का क्या मतलब है: https://support.sonatype.com/entries/22189106-How-can-I-programatically-upload-an-artifact-into-Nexus-

इस कार्य के लिए अनुमति देने के लिए, मैंने व्यवस्थापक GUI में एक नई भूमिका बनाई और मैंने उस भूमिका में दो विशेषाधिकार जोड़े: Artifact Download और Artifact Upload। मानक "रेपो: ऑल मैवेन रिपोजिटरीज़ (पूर्ण नियंत्रण)" - भूमिका पर्याप्त नहीं है। आपको यह नेस्ट एपीआई प्रलेखन में नहीं मिलेगा जो नेक्सस सर्वर के साथ बंडल में आता है, इसलिए ये पैरामीटर भविष्य में बदल सकते हैं।

पर एक Sonatype JIRA मुद्दा है, यह उल्लेख किया गया था कि वे "सबसे अधिक संभावना इस वर्ष बाद में आने वाली रिलीज़ में REST API (और जिस तरह से यह के प्रलेखन उत्पन्न होता है) ओवरहाल करने के लिए, जा रहे हैं"।


मान लें कि हम जेनकिन्स से प्रकाशित करते हैं, और केवल बिल्ड उपयोगकर्ताओं को नेक्सस पर प्रकाशित करने की अनुमति देते हैं, आप सादे पासवर्ड समस्या का प्रबंधन कैसे करते हैं? क्या जेनकिन्स में अपलोड के लिए एक प्लगइन है इसलिए हम जेनकिंस क्रेडेंशियल्स का उपयोग कर सकते हैं?
जिरोंग हू

8

इन आदेशों का उपयोग करने की आवश्यकता नहीं है .. आप अपने JAR को GAV मापदंडों का उपयोग करके अपलोड करने के लिए सीधे नेक्सस वेब इंटरफेस का उपयोग कर सकते हैं।

यहां छवि विवरण दर्ज करें

इसलिए यह बहुत सरल है।


24
एक जीयूआई मदद नहीं करता है; मुझे एक कमांड-लाइन स्क्रिप्ट के माध्यम से अपलोड करने में सक्षम होने की आवश्यकता है जो एक बिल्ड प्रक्रिया के हिस्से के रूप में उपयोग की जाती है।
एडम वंडेनबर्ग

ठीक है, यह एक HTTP पोस्ट अनुरोध का अनुवाद है, क्या आपको नहीं लगता?
यंगवे स्नेन लिंडल

5
@YngveSneenLindal ज़रूर, लेकिन इसका मतलब यह नहीं है कि उन POST तर्क सार्वजनिक रूप से उपयोग करने के लिए एक अच्छी तरह से परिभाषित एपीआई हैं।
केन विलियम्स

@KenWilliams ज़रूर, मैंने दावा नहीं किया कि या तो। लेकिन वे काम करेंगे और एक समाधान का प्रतिनिधित्व करेंगे, यह मेरी बात है।
यंगवे स्नेन लिंडल

कम से कम, हमारे Sonatype Nexus ™ 2.11.1-01 के लिए मुझे उपयोगकर्ता को विशेषाधिकार प्रदान करना था Artifact Upload। दुर्भाग्य से, मैं इस उल्लेख में दिए गए डॉक्स में कुछ भी नहीं पा सका ... (संपादित करें: मैं देखता हूं, एड मैं पहले ही इस बात का संकेत दे चुका हूं )
अल्बर्टो

8

आप संबंधित कुछ भी MAVEN का उपयोग किए बिना ABSOLUTELY कर सकते हैं । मैं व्यक्तिगत रूप से Nava HttpClient (v1.8.16, java6 का समर्थन करने के लिए) का उपयोग करता हूं।

जो भी कारण हो, सोनाटाइप इसे अविश्वसनीय बनाता है पता लगाने के लिए मुश्किल कि सही यूआरएल, हेडर और पेलोड क्या होने चाहिए; और मुझे ट्रैफ़िक सूँघना था और अनुमान लगाना था ... वहाँ कुछ मुश्किल से उपयोगी ब्लॉग / दस्तावेज हैं, हालाँकि यह या तो अप्रासंगिक है oss.sonatype.org, या यह XML आधारित है (और मुझे पता चला कि यह काम भी नहीं करता है)। उनके भाग, IMHO, और उम्मीद है कि भविष्य के चाहने वालों के लिए इस दस्तावेज़ को बकवास उपयोगी पा सकते हैं। Https://stackoverflow.com/a/33414423/2101812 को उनके पोस्ट के लिए बहुत धन्यवाद , क्योंकि इससे बहुत मदद मिली।

यदि आप इसके अलावा कहीं और जारी करते हैं oss.sonatype.org, तो इसे सही मेजबान के साथ जो कुछ भी है उसे बदल दें।

यहाँ (CC0 लाइसेंस प्राप्त) कोड है जो मैंने इसे पूरा करने के लिए लिखा था। कहाँ पेprofile अपने sonatype / गठजोड़ profileID (जैसे है 4364f3bbaf163) और repo(जैसे comdorkbox-1003) प्रतिक्रिया जब आप अपने प्रारंभिक पोम / जार अपलोड से पार्स कर रहे हैं।

रेपो बंद करें:

/**
 * Closes the repo and (the server) will verify everything is correct.
 * @throws IOException
 */
private static
String closeRepo(final String authInfo, final String profile, final String repo, final String nameAndVersion) throws IOException {

    String repoInfo = "{'data':{'stagedRepositoryId':'" + repo + "','description':'Closing " + nameAndVersion + "'}}";
    RequestBuilder builder = new RequestBuilder("POST");
    Request request = builder.setUrl("https://oss.sonatype.org/service/local/staging/profiles/" + profile + "/finish")
                             .addHeader("Content-Type", "application/json")
                             .addHeader("Authorization", "Basic " + authInfo)

                             .setBody(repoInfo.getBytes(OS.UTF_8))

                             .build();

    return sendHttpRequest(request);
}

रेपो को बढ़ावा दें:

/**
 * Promotes (ie: release) the repo. Make sure to drop when done
 * @throws IOException
 */
private static
String promoteRepo(final String authInfo, final String profile, final String repo, final String nameAndVersion) throws IOException {

    String repoInfo = "{'data':{'stagedRepositoryId':'" + repo + "','description':'Promoting " + nameAndVersion + "'}}";
    RequestBuilder builder = new RequestBuilder("POST");
    Request request = builder.setUrl("https://oss.sonatype.org/service/local/staging/profiles/" + profile + "/promote")
                     .addHeader("Content-Type", "application/json")
                     .addHeader("Authorization", "Basic " + authInfo)

                     .setBody(repoInfo.getBytes(OS.UTF_8))

                     .build();
    return sendHttpRequest(request);
}

ड्रॉप रेपो:

/**
 * Drops the repo
 * @throws IOException
 */
private static
String dropRepo(final String authInfo, final String profile, final String repo, final String nameAndVersion) throws IOException {

    String repoInfo = "{'data':{'stagedRepositoryId':'" + repo + "','description':'Dropping " + nameAndVersion + "'}}";
    RequestBuilder builder = new RequestBuilder("POST");
    Request request = builder.setUrl("https://oss.sonatype.org/service/local/staging/profiles/" + profile + "/drop")
                     .addHeader("Content-Type", "application/json")
                     .addHeader("Authorization", "Basic " + authInfo)

                     .setBody(repoInfo.getBytes(OS.UTF_8))

                     .build();

    return sendHttpRequest(request);
}

हस्ताक्षर की कलियाँ हटाएँ:

/**
 * Deletes the extra .asc.md5 and .asc.sh1 'turds' that show-up when you upload the signature file. And yes, 'turds' is from sonatype
 * themselves. See: https://issues.sonatype.org/browse/NEXUS-4906
 * @throws IOException
 */
private static
void deleteSignatureTurds(final String authInfo, final String repo, final String groupId_asPath, final String name,
                          final String version, final File signatureFile)
                throws IOException {

    String delURL = "https://oss.sonatype.org/service/local/repositories/" + repo + "/content/" +
                    groupId_asPath + "/" + name + "/" + version + "/" + signatureFile.getName();

    RequestBuilder builder;
    Request request;

    builder = new RequestBuilder("DELETE");
    request = builder.setUrl(delURL + ".sha1")
                     .addHeader("Authorization", "Basic " + authInfo)
                     .build();
    sendHttpRequest(request);

    builder = new RequestBuilder("DELETE");
    request = builder.setUrl(delURL + ".md5")
                     .addHeader("Authorization", "Basic " + authInfo)
                     .build();
    sendHttpRequest(request);
}

फ़ाइल अपलोड:

    public
    String upload(final File file, final String extension, String classification) throws IOException {

        final RequestBuilder builder = new RequestBuilder("POST");
        final RequestBuilder requestBuilder = builder.setUrl(uploadURL);
        requestBuilder.addHeader("Authorization", "Basic " + authInfo)

                      .addBodyPart(new StringPart("r", repo))
                      .addBodyPart(new StringPart("g", groupId))
                      .addBodyPart(new StringPart("a", name))
                      .addBodyPart(new StringPart("v", version))
                      .addBodyPart(new StringPart("p", "jar"))
                      .addBodyPart(new StringPart("e", extension))
                      .addBodyPart(new StringPart("desc", description));


        if (classification != null) {
            requestBuilder.addBodyPart(new StringPart("c", classification));
        }

        requestBuilder.addBodyPart(new FilePart("file", file));
        final Request request = requestBuilder.build();

        return sendHttpRequest(request);
    }

EDIT1:

रेपो के लिए गतिविधि / स्थिति कैसे प्राप्त करें

/**
 * Gets the activity information for a repo. If there is a failure during verification/finish -- this will provide what it was.
 * @throws IOException
 */
private static
String activityForRepo(final String authInfo, final String repo) throws IOException {

    RequestBuilder builder = new RequestBuilder("GET");
    Request request = builder.setUrl("https://oss.sonatype.org/service/local/staging/repository/" + repo + "/activity")
                             .addHeader("Content-Type", "application/json")
                             .addHeader("Authorization", "Basic " + authInfo)

                             .build();

    return sendHttpRequest(request);
}

6

Nexus के विरुद्ध आपको जो कॉल करने की आवश्यकता है, वे REST एपि कॉल हैं।

मावेन-नेक्सस-प्लगइन एक मावेन प्लगइन है जिसका उपयोग आप इन कॉल करने के लिए कर सकते हैं। आप आवश्यक गुणों के साथ एक डमी पोम बना सकते हैं और मावेन प्लगइन के माध्यम से उन कॉल कर सकते हैं।

कुछ इस तरह:

mvn -DserverAuthId=sonatype-nexus-staging -Dauto=true nexus:staging-close

मानी गई बातें:

  1. आपने अपने ~ / .m2 / settings.xml में एक सर्वर को परिभाषित किया है जिसका नाम sonatype-nexus-staging है जो आपके sonatype उपयोगकर्ता और पासवर्ड सेट अप के साथ है - यदि आप स्नैपशॉट्स परिनियोजित कर रहे हैं, तो आपने संभवतः ऐसा पहले ही कर लिया होगा। लेकिन आप अधिक जानकारी पा सकते हैं यहां
  2. आपकी स्थानीय सेटिंग। Xml में यहाँ निर्दिष्ट के रूप में नेक्सस प्लगइन्स शामिल हैं
  3. आपकी वर्तमान निर्देशिका में बैठे pom.xml की परिभाषा में सही Maven निर्देशांक हैं। यदि नहीं, तो आप कमांड लाइन पर GroupId, विरूपण साक्ष्य और संस्करण निर्दिष्ट कर सकते हैं।
  4. -Dauto = true इंटरैक्टिव संकेतों को बंद कर देगा ताकि आप इसे स्क्रिप्ट कर सकें।

अंततः, यह सब नेक्सस में REST कॉल का निर्माण कर रहा है। एक पूर्ण नेक्सस REST एपी है, लेकिन मुझे इसके लिए दस्तावेज खोजने में बहुत कम भाग्य मिला है जो एक पेवेल के पीछे नहीं है। आप ऊपर दिए गए प्लगइन के लिए डिबग मोड को चालू कर सकते हैं और इसे उपयोग करके समझ सकते हैं-Dnexus.verboseDebug=true -X

आप सैद्धांतिक रूप से UI में भी जा सकते हैं, फायरबग नेट पैनल को चालू कर सकते हैं, और / सेवा POST के लिए देख सकते हैं और साथ ही एक रास्ता भी निकाल सकते हैं।


3

उन लोगों के लिए जिन्हें जावा में इसकी आवश्यकता है, Apache httpcompenders 4.0 का उपयोग करते हुए:

public class PostFile {
    protected HttpPost httppost ;
    protected MultipartEntity mpEntity; 
    protected File filePath;

    public PostFile(final String fullUrl, final String filePath){
        this.httppost = new HttpPost(fullUrl);
        this.filePath = new File(filePath);        
        this.mpEntity = new MultipartEntity();
    }

    public void authenticate(String user, String password){
        String encoding = new String(Base64.encodeBase64((user+":"+password).getBytes()));
        httppost.setHeader("Authorization", "Basic " + encoding);
    }
    private void addParts() throws UnsupportedEncodingException{
        mpEntity.addPart("r", new StringBody("repository id"));
        mpEntity.addPart("g", new StringBody("group id"));
        mpEntity.addPart("a", new StringBody("artifact id"));
        mpEntity.addPart("v", new StringBody("version"));
        mpEntity.addPart("p", new StringBody("packaging"));
        mpEntity.addPart("e", new StringBody("extension"));

        mpEntity.addPart("file", new FileBody(this.filePath));

    }

    public String post() throws ClientProtocolException, IOException {
        HttpClient httpclient = new DefaultHttpClient();
        httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        addParts();
        httppost.setEntity(mpEntity);
        HttpResponse response = httpclient.execute(httppost);

        System.out.println("executing request " + httppost.getRequestLine());
        System.out.println(httppost.getEntity().getContentLength());

        HttpEntity resEntity = response.getEntity();

        String statusLine = response.getStatusLine().toString();
        System.out.println(statusLine);
        if (resEntity != null) {
            System.out.println(EntityUtils.toString(resEntity));
        }
        if (resEntity != null) {
            resEntity.consumeContent();
        }
        return statusLine;
    }
}

पहिला पद। मैं जावा के लिए higlighting जोड़ने की कोशिश की है, लेकिन यह नहीं मिला।
मैकमोसेफ

3

माणिक में https://github.com/RiotGames/nexus_cli Sonatype Nexus REST कॉल के आसपास एक CLI आवरण।

उपयोग उदाहरण:

nexus-cli push_artifact com.mycompany.artifacts:myartifact:tgz:1.0.0 ~/path/to/file/to/push/myartifact.tgz

कॉन्फ़िगरेशन .nexus_cliफ़ाइल के माध्यम से किया जाता है ।

url:            "http://my-nexus-server/nexus/"
repository:     "my-repository-id"
username:       "username"
password:       "password"

2

आप कर्ल का उपयोग करके प्रत्यक्ष तैनाती विधि का भी उपयोग कर सकते हैं। इसके लिए आपको अपनी फ़ाइल के लिए एक pom की आवश्यकता नहीं है, लेकिन यह भी जेनरेट नहीं होगी, इसलिए यदि आप चाहते हैं, तो आपको इसे अलग से अपलोड करना होगा।

यहाँ आदेश है:

version=1.2.3
artefact="myartefact"
repoId=yourrepository
groupId=org.myorg
REPO_URL=http://localhost:8081/nexus

curl -u nexususername:nexuspassword --upload-file filename.tgz $REPO_URL/content/repositories/$repoId/$groupId/$artefact/$version/$artefact-$version.tgz

"कलाकृतियों" का अर्थ नहीं है
राम

1

यदि आपको एक सुविधाजनक कमांड लाइन इंटरफ़ेस या अजगर एपीआई की आवश्यकता है, तो रिपॉजिटरी टूल देखें

इसका उपयोग करते हुए, आप कमांड के साथ आर्टवर्क को नेक्सस पर अपलोड कर सकते हैं

artifact upload foo-1.2.3.ext releases com.fooware

इसे काम करने के लिए, आपको कुछ पर्यावरण चर भी निर्धारित करने होंगे

export REPOSITORY_URL=https://repo.example.com
export REPOSITORY_USER=admin
export REPOSITORY_PASSWORD=mysecretpassword

0

आप मैन्युअल रूप से नेक्सस सर्वर में अपलोड कलाकृतियों के बटन पर क्लिक करके कलाकृतियों को अपलोड कर सकते हैं और अपलोड करने के लिए आवश्यक जीएवी गुण प्रदान कर सकते हैं (यह आमतौर पर कलाकृतियों को संग्रहीत करने के लिए फ़ाइल संरचना है)


0

Nexus OSS के हाल के संस्करणों के लिए (> = 3.9.0)

https://support.sonatype.com/hc/en-us/articles/115006744008-How-can-I-programmatically-upload-files-into-Nexus-3-

संस्करणों का संस्करण 3.9.0 से 3.13.0:

curl -D - -u user:pass -X POST "https://nexus.domain/nexus/service/rest/beta/components?repository=somerepo" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "raw.directory=/test/" -F "raw.asset1=@test.txt;type=application/json" -F "raw.asset1.filename=test.txt"

-1

@Adam Vandenberg Java कोड के लिए POST से Nexus तक। https://github.com/manbalagan/nexusuploader

public class NexusRepository implements RepoTargetFactory {

    String DIRECTORY_KEY= "raw.directory";
    String ASSET_KEY= "raw.asset1";
    String FILENAME_KEY= "raw.asset1.filename";

    String repoUrl;
    String userName;
    String password;

    @Override
    public void setRepoConfigurations(String repoUrl, String userName, String password) {
        this.repoUrl = repoUrl;
        this.userName = userName;
        this.password = password;
    }

    public String pushToRepository() {
        HttpClient httpclient = HttpClientBuilder.create().build();
        HttpPost postRequest = new HttpPost(repoUrl) ;
        String auth = userName + ":" + password;
        byte[] encodedAuth = Base64.encodeBase64(
                auth.getBytes(StandardCharsets.ISO_8859_1));
        String authHeader = "Basic " + new String(encodedAuth);
        postRequest.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
        try
        {
            byte[] packageBytes = "Hello. This is my file content".getBytes();
            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
            InputStream packageStream = new ByteArrayInputStream(packageBytes);
            InputStreamBody inputStreamBody = new InputStreamBody(packageStream, ContentType.APPLICATION_OCTET_STREAM);
            multipartEntityBuilder.addPart(DIRECTORY_KEY, new StringBody("DIRECTORY"));
            multipartEntityBuilder.addPart(FILENAME_KEY, new StringBody("MyFile.txt"));
            multipartEntityBuilder.addPart(ASSET_KEY, inputStreamBody);
            HttpEntity entity = multipartEntityBuilder.build();
            postRequest.setEntity(entity); ;

            HttpResponse response = httpclient.execute(postRequest) ;
            if (response != null)
            {
                System.out.println(response.getStatusLine().getStatusCode());
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace() ;
        }
        return null;
    }

}

-2

आप इसके बजाय कर्ल का उपयोग कर सकते हैं।

version=1.2.3
artifact="artifact"
repoId=repositoryId
groupId=org/myorg
REPO_URL=http://localhost:8081/nexus

curl -u username:password --upload-file filename.tgz $REPO_URL/content/repositories/$repoId/$groupId/$artefact/$version/$artifact-$version.tgz

यह उत्तर सही नहीं है। कर्ल के साथ, GroupId को org / myorg (डॉट को स्थानापन्न) के रूप में दर्शाया जाना चाहिए। "स्लैश के साथ" / ")
Madduci
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.