Newer
Older
# Copyright (C) 2017-2019 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information
import click
from swh.deposit.config import setup_django_for
from swh.deposit.cli import deposit
@deposit.group('admin')
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
@click.option('--config-file', '-C', default=None,
type=click.Path(exists=True, dir_okay=False,),
help="Optional extra configuration file.")
@click.option('--platform', default='development',
type=click.Choice(['development', 'production']),
help='development or production platform')
@click.pass_context
def admin(ctx, config_file, platform):
"""Server administration tasks (manipulate user or collections)"""
# configuration happens here
setup_django_for(platform, config_file=config_file)
@admin.group('user')
@click.pass_context
def user(ctx):
"""Manipulate user."""
# configuration happens here
pass
def _create_collection(name):
"""Create the collection with name if it does not exist.
Args:
name (str): collection's name
Returns:
collection (DepositCollection): the existing collection object
(created or not)
"""
# to avoid loading too early django namespaces
from swh.deposit.models import DepositCollection
try:
collection = DepositCollection.objects.get(name=name)
click.echo('Collection %s exists, nothing to do.' % name)
except DepositCollection.DoesNotExist:
click.echo('Create new collection %s' % name)
collection = DepositCollection.objects.create(name=name)
click.echo('Collection %s created' % name)
return collection
@user.command('create')
@click.option('--username', required=True, help="User's name")
@click.option('--password', required=True,
help="Desired user's password (plain).")
@click.option('--firstname', default='', help="User's first name")
@click.option('--lastname', default='', help="User's last name")
@click.option('--email', default='', help="User's email")
@click.option('--collection', help="User's collection")
@click.option('--provider-url', default='', help="Provider URL")
@click.option('--domain', default='', help="The domain")
@click.pass_context
def user_create(ctx, username, password, firstname, lastname, email,
collection, provider_url, domain):
"""Create a user with some needed information (password, collection)
If the collection does not exist, the collection is then created
alongside.
The password is stored encrypted using django's utilies.
"""
# to avoid loading too early django namespaces
from swh.deposit.models import DepositClient
# If collection is not provided, fallback to username
if not collection:
collection = username
click.echo('collection: %s' % collection)
# create the collection if it does not exist
collection = _create_collection(collection)
# user create/update
try:
user = DepositClient.objects.get(username=username)
click.echo('User %s exists, updating information.' % user)
user.set_password(password)
except DepositClient.DoesNotExist:
click.echo('Create new user %s' % username)
user = DepositClient.objects.create_user(
username=username,
password=password)
user.collections = [collection.id]
user.first_name = firstname
user.last_name = lastname
user.email = email
user.is_active = True
user.provider_url = provider_url
user.domain = domain
user.save()
click.echo('Information registered for user %s' % user)
@user.command('list')
@click.pass_context
def user_list(ctx):
"""List existing users.
This entrypoint is not paginated yet as there is not a lot of
entry.
"""
# to avoid loading too early django namespaces
from swh.deposit.models import DepositClient
users = DepositClient.objects.all()
if not users:
output = 'Empty user list'
else:
output = '\n'.join((user.username for user in users))
click.echo(output)
@user.command('exists')
@click.argument('username', required=True)
@click.pass_context
def user_exists(ctx, username):
"""Check if user exists.
"""
# to avoid loading too early django namespaces
from swh.deposit.models import DepositClient
try:
DepositClient.objects.get(username=username)
click.echo('User %s exists.' % username)
ctx.exit(0)
except DepositClient.DoesNotExist:
click.echo('User %s does not exist.' % username)
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
@admin.group('collection')
@click.pass_context
def collection(ctx):
"""Manipulate collections."""
pass
@collection.command('create')
@click.option('--name', required=True, help="Collection's name")
@click.pass_context
def collection_create(ctx, name):
_create_collection(name)
@collection.command('list')
@click.pass_context
def collection_list(ctx):
"""List existing collections.
This entrypoint is not paginated yet as there is not a lot of
entry.
"""
# to avoid loading too early django namespaces
from swh.deposit.models import DepositCollection
collections = DepositCollection.objects.all()
if not collections:
output = 'Empty collection list'
else:
output = '\n'.join((col.name for col in collections))
click.echo(output)
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
@admin.group('deposit')
@click.pass_context
def deposit(ctx):
"""Manipulate deposit."""
pass
@deposit.command('reschedule')
@click.option('--deposit-id', required=True, help="Deposit identifier")
@click.pass_context
def deposit_reschedule(ctx, deposit_id):
"""Reschedule the deposit loading
This will:
- check the deposit's status to something reasonable (failed or done). That
means that the checks have passed alright but something went wrong during
the loading (failed: loading failed, done: loading ok, still for some
reasons as in bugs, we need to reschedule it)
- reset the deposit's status to 'verified' (prior to any loading but after
the checks which are fine) and removes the different archives'
identifiers (swh-id, ...)
- trigger back the loading task through the scheduler
"""
# to avoid loading too early django namespaces
from datetime import datetime
from swh.deposit.models import Deposit
from swh.deposit.config import (
DEPOSIT_STATUS_LOAD_SUCCESS, DEPOSIT_STATUS_LOAD_FAILURE,
DEPOSIT_STATUS_VERIFIED, SWHDefaultConfig,
)
try:
deposit = Deposit.objects.get(pk=deposit_id)
except Deposit.DoesNotExist:
click.echo('Deposit %s does not exist.' % deposit_id)
ctx.exit(1)
# Check the deposit is in a reasonable state
accepted_statuses = [
DEPOSIT_STATUS_LOAD_SUCCESS, DEPOSIT_STATUS_LOAD_FAILURE
]
if deposit.status == DEPOSIT_STATUS_VERIFIED:
click.echo('Deposit %s\'s status already set for rescheduling.' % (
deposit_id))
ctx.exit(0)
if deposit.status not in accepted_statuses:
click.echo('Deposit %s\'s status be one of %s.' % (
deposit_id, ', '.join(accepted_statuses)))
ctx.exit(1)
task_id = deposit.load_task_id
if not task_id:
click.echo('Deposit %s cannot be rescheduled. It misses the '
'associated task.' % deposit_id)
ctx.exit(1)
# Reset the deposit's state
deposit.swh_id = None
deposit.swh_id_context = None
deposit.swh_anchor_id = None
deposit.swh_anchor_id_context = None
deposit.status = DEPOSIT_STATUS_VERIFIED
deposit.save()
# Trigger back the deposit
scheduler = SWHDefaultConfig().scheduler
scheduler.set_status_tasks(
[task_id], status='next_run_not_scheduled',
next_run=datetime.now())