blob: a9b24c55db90f970ab37e3bd6aa78d5aa69a589b [file] [log] [blame]
Ray Milkeyebc673f2018-07-20 16:51:55 -07001#!/usr/bin/env python
2"""
3 Copyright 2018-present Open Networking Foundation
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16"""
17
18from subprocess import call
19import tempfile
20import hashlib
21import requests, os
22import xml.etree.ElementTree, shutil
Ray Milkeyf77ea412018-08-10 17:37:28 -070023import time
Ray Milkeyebc673f2018-07-20 16:51:55 -070024
25SONATYPE_USER=os.environ.get("SONATYPE_USER")
26SONATYPE_PASSWORD=os.environ.get("SONATYPE_PASSWORD")
27SONATYPE_PROFILE=os.environ.get("SONATYPE_PROFILE")
Ray Milkeyebc673f2018-07-20 16:51:55 -070028
29CREATE_REPO_REQUEST_TEMPLATE = '''\
30<promoteRequest>
31 <data>
32 <description>%(description)</description>
33 </data>
34</promoteRequest>
35'''
36
37CLOSE_REPO_REQUEST_TEMPLATE = '''\
38<promoteRequest>
39 <data>
40 <description>%(description)</description>
41 <stagedRepositoryId>%(repo_id)</stagedRepositoryId>
42 </data>
43</promoteRequest>
44'''
45
Ray Milkeyf77ea412018-08-10 17:37:28 -070046CLOSE_RETRY_ATTEMPTS = 12 * 2
47
Ray Milkeyebc673f2018-07-20 16:51:55 -070048def hashlib_compute(hash, input_file, output_file):
49 with open(input_file, 'rb') as f:
50 for block in iter(lambda: f.read(100000), b''):
51 hash.update(block)
52 md5_string = hash.hexdigest()
53 output = open(output_file, "w")
54 output.write(md5_string + "\n")
55 f.close()
56 output.close()
57
58
Ray Milkey7f46b1f2018-07-24 19:01:58 -070059def generate_metadata_files(input_file, dest):
Ray Milkeyebc673f2018-07-20 16:51:55 -070060 # create a temporary directory to hold the metadata files
61 global tempdir
Ray Milkey7f46b1f2018-07-24 19:01:58 -070062 base_metadata_filename = tempdir + "/" + os.path.basename(dest)
Ray Milkeyebc673f2018-07-20 16:51:55 -070063
64 files = []
65
Ray Milkeyc161f822018-11-14 14:21:17 -080066 if destination_repo_url is not None:
67 # generate maven metadata files: signature, MD5, and SHA
Ray Milkeyebc673f2018-07-20 16:51:55 -070068
Ray Milkeyc161f822018-11-14 14:21:17 -080069 # generate the signature file
70 signature_filename = base_metadata_filename + ".asc"
71 call(["gpg", "--armor", "--detach-sig", "--output", signature_filename, input_file])
72 files.append(signature_filename)
Ray Milkeyebc673f2018-07-20 16:51:55 -070073
Ray Milkeyc161f822018-11-14 14:21:17 -080074 # generate the md5 checksum file
75 md5_filename = base_metadata_filename + ".md5"
76 md5 = hashlib.md5()
77 hashlib_compute(md5, input_file, md5_filename)
78 files.append(md5_filename)
79
80 # generate the SHA checksum file
81 sha1_filename = base_metadata_filename + ".sha1"
82 sha1 = hashlib.sha1()
83 hashlib_compute(sha1, input_file, sha1_filename)
84 files.append(sha1_filename)
Ray Milkeyebc673f2018-07-20 16:51:55 -070085
Ray Milkey7f46b1f2018-07-24 19:01:58 -070086 # generate the base artifact
87 base_artifact_filename = base_metadata_filename
88 shutil.copyfile(input_file, base_artifact_filename)
89 files.append(base_artifact_filename)
90
Ray Milkeyebc673f2018-07-20 16:51:55 -070091 return files
92
93
94def create_staging_repo(description):
Ray Milkeyd111751b2018-07-24 10:14:02 -070095 if destination_repo_url is None:
96 return None
Ray Milkeyebc673f2018-07-20 16:51:55 -070097 create_request = CREATE_REPO_REQUEST_TEMPLATE.replace("%(description)", description)
Ray Milkeyd111751b2018-07-24 10:14:02 -070098 url = "https://" + destination_repo_url + "/service/local/staging/profiles" + "/" + SONATYPE_PROFILE + "/start"
Ray Milkeyebc673f2018-07-20 16:51:55 -070099 headers = {'Content-Type': 'application/xml'}
100 r = requests.post(url, create_request, headers=headers, auth=(SONATYPE_USER, SONATYPE_PASSWORD))
101 root = xml.etree.ElementTree.fromstring(r.text)
102 repo_id = root.find("data").find("stagedRepositoryId").text
Ray Milkeyebc673f2018-07-20 16:51:55 -0700103 return repo_id
104
105
106def close_staging_repo(description, repo_id):
Ray Milkey245d1192018-08-14 17:49:33 -0700107 if destination_repo_url is None:
Ray Milkeyd111751b2018-07-24 10:14:02 -0700108 return
Ray Milkeyebc673f2018-07-20 16:51:55 -0700109 close_request = CLOSE_REPO_REQUEST_TEMPLATE.replace("%(description)", description).replace("%(repo_id)", repo_id)
Ray Milkeyd111751b2018-07-24 10:14:02 -0700110 url = "https://" + destination_repo_url + "/service/local/staging/profiles" + "/" + SONATYPE_PROFILE + "/finish"
Ray Milkeyebc673f2018-07-20 16:51:55 -0700111 headers = {'Content-Type': 'application/xml'}
112 r = requests.post(url, close_request, headers=headers, auth=(SONATYPE_USER, SONATYPE_PASSWORD))
113
114
Ray Milkeyf77ea412018-08-10 17:37:28 -0700115def wait_for_staging_repo(description, repo_id):
Ray Milkeycb8ea062018-08-14 19:31:47 -0700116 if destination_repo_url is None:
Ray Milkeyf77ea412018-08-10 17:37:28 -0700117 return
Ray Milkeycb8ea062018-08-14 19:31:47 -0700118 base_url = "https://" + destination_repo_url + "/service/local/staging/profiles" + "/" + SONATYPE_PROFILE
Ray Milkeyf77ea412018-08-10 17:37:28 -0700119 close_request = CLOSE_REPO_REQUEST_TEMPLATE.replace("%(description)", description).replace("%(repo_id)", repo_id)
120 url = base_url + "/finish"
121 headers = {'Content-Type': 'application/xml'}
122 repo_query_url = "https://oss.sonatype.org/service/local/staging/repository/" + repo_id
123
124 attempt = 1
125 print ("waiting for repo to close...")
126 while True:
127 r = requests.get(repo_query_url, close_request, headers=headers, auth=(SONATYPE_USER, SONATYPE_PASSWORD))
128 root = xml.etree.ElementTree.fromstring(r.text)
129 transitioning = root.find("transitioning").text
130 if transitioning != "true":
131 break
132 if attempt == CLOSE_RETRY_ATTEMPTS:
133 print ("Unable to close repo")
134 sys.exit(1)
135 attempt = attempt + 1
136 time.sleep(5)
137 print ("Repo closed successfully")
138
139
Ray Milkeyebc673f2018-07-20 16:51:55 -0700140def stage_file(file, repo_id, dest):
Ray Milkey7f46b1f2018-07-24 19:01:58 -0700141 filename_in_repo = os.path.dirname(dest) + "/" + os.path.basename(file)
Ray Milkeyd111751b2018-07-24 10:14:02 -0700142 if destination_repo_url is not None:
143 # deploy to Nexus repo
144 upload_base = "https://" + destination_repo_url + "/service/local/staging/deployByRepositoryId"
Ray Milkey7f46b1f2018-07-24 19:01:58 -0700145 url = upload_base + "/" + repo_id + "/" + filename_in_repo
Ray Milkeyd111751b2018-07-24 10:14:02 -0700146 headers = {'Content-Type': 'application/xml'}
147 with open(file, 'rb') as f:
Ray Milkey7f46b1f2018-07-24 19:01:58 -0700148 r = requests.post(url, data=f.read(), headers=headers, auth=(SONATYPE_USER, SONATYPE_PASSWORD))
149 if r.status_code != 201:
150 print (r.status_code)
151 print (r.text)
152 sys.exit(1)
Ray Milkeyd111751b2018-07-24 10:14:02 -0700153 else:
154 # deploy to local repo
Ray Milkey7f46b1f2018-07-24 19:01:58 -0700155 file_in_local_repo = os.path.expanduser(local_maven_repo + "/" + filename_in_repo)
156 dir_in_local_repo = os.path.dirname(file_in_local_repo)
157 if not os.path.isdir(dir_in_local_repo):
158 os.makedirs(dir_in_local_repo)
159 shutil.copyfile(src, file_in_local_repo)
Ray Milkeyebc673f2018-07-20 16:51:55 -0700160
161
162def stage_files(files, dest):
163 for file in files:
164 stage_file(file=file, repo_id=repo_id, dest=dest)
165
166
167def upload_file(src, dest):
Ray Milkey7f46b1f2018-07-24 19:01:58 -0700168 print ("publishing: " + dest.replace("org/onosproject", ""))
169 files = generate_metadata_files(src, dest)
Ray Milkeyebc673f2018-07-20 16:51:55 -0700170 stage_files(files, dest)
171
172
173if __name__ == '__main__':
174 import sys
175
176 if len(sys.argv) < 2:
Ray Milkeyd111751b2018-07-24 10:14:02 -0700177 print 'USAGE: upload-maven-artifacts catalog-file-name [nexus root url]'
Ray Milkeyebc673f2018-07-20 16:51:55 -0700178 sys.exit(1)
179
180 input_list_file = sys.argv[1]
Ray Milkeyd111751b2018-07-24 10:14:02 -0700181
182 local_maven_repo = None
183 destination_repo_url = None
184
185 if len(sys.argv) == 3:
186 destination_repo_url = sys.argv[2]
187 else:
188 local_maven_repo = os.environ.get("MAVEN_REPO")
189 if local_maven_repo is None:
190 local_maven_repo = "~/.m2/repository"
191
192 if destination_repo_url is not None:
193 if SONATYPE_USER is None:
194 print "Environment variable SONATYPE_USER must be set"
195 sys.exit(1)
196
197 if SONATYPE_PASSWORD is None:
198 print "Environment variable SONATYPE_PASSWORD must be set"
199 sys.exit(1)
200
201 if SONATYPE_PROFILE is None:
202 print "Environment variable SONATYPE_PROFILE must be set"
203 sys.exit(1)
204
205 print ("Uploading to remote repo: " + destination_repo_url)
206 else:
207 print ("Installing in local repo: " + local_maven_repo)
208
Ray Milkeyebc673f2018-07-20 16:51:55 -0700209 list_file = open(input_list_file, "r")
210 lines = list_file.readlines()
211 list_file.close()
212
Ray Milkeyd111751b2018-07-24 10:14:02 -0700213 tempdir = tempfile.mkdtemp(prefix="upload-maven-artifacts-")
Ray Milkeyebc673f2018-07-20 16:51:55 -0700214 description = "test repo"
215 repo_id = create_staging_repo(description)
216 for line in lines:
217 s = line.split()
218 src = s[0]
219 dest = s[1]
220 upload_file(src, dest)
221 close_staging_repo(repo_id=repo_id, description=description)
Ray Milkeyf77ea412018-08-10 17:37:28 -0700222 wait_for_staging_repo(repo_id=repo_id, description=description)
Ray Milkeyebc673f2018-07-20 16:51:55 -0700223 shutil.rmtree(tempdir)