Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 4.4.x] [Fixes #12326] Assets: implement migration for old uploaded files #12611

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
Empty file.
140 changes: 140 additions & 0 deletions geonode/assets/management/commands/migrate_file_to_assets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#########################################################################
#
# Copyright (C) 2024 OSGeo
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################

import os
import sys
import shutil
import logging
from django.conf import settings
from geonode.assets.local import LocalAssetHandler
from geonode.assets.models import LocalAsset
from geonode.base.management.commands.helpers import confirm
from django.core.management.base import BaseCommand
from geonode.geoserver.helpers import gs_catalog

Check warning on line 29 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L20-L29

Added lines #L20 - L29 were not covered by tests

from geonode.base.models import ResourceBase

Check warning on line 31 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L31

Added line #L31 was not covered by tests

logger = logging.getLogger()
handler = logging.StreamHandler(sys.stdout)
logger.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)

Check warning on line 38 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L33-L38

Added lines #L33 - L38 were not covered by tests


class Command(BaseCommand):

Check warning on line 41 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L41

Added line #L41 was not covered by tests

help = """

Check warning on line 43 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L43

Added line #L43 was not covered by tests
Migrate the files from MEDIA_ROOT to ASSETS_ROOT, update LocalAsset.location and GeoServer
REF: https://github.com/GeoNode/geonode/issues/12326
"""

def add_arguments(self, parser):
parser.add_argument(

Check warning on line 49 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L48-L49

Added lines #L48 - L49 were not covered by tests
'-n',
'--no-input',
dest='noinput',
default=False,
action='store_true',
help='Does not ask for confirmation for the run'
)
parser.add_argument(

Check warning on line 57 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L57

Added line #L57 was not covered by tests
'-d',
'--dryrun',
dest='dryrun',
default=False,
action='store_true',
help='Perform a dryrun, will show the File to be moved, their new path and the file to be deleted'
)

def handle(self, **options):
question = "By running this command you are going to move all the files of your Resources into the ASSETS_ROOT. Do you want to continue?"

Check warning on line 67 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L66-L67

Added lines #L66 - L67 were not covered by tests

if not options.get('noinput'):
result = confirm(question, resp=True)

Check warning on line 70 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L70

Added line #L70 was not covered by tests
if not result:
return

Check warning on line 72 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L72

Added line #L72 was not covered by tests

dryrun = options.get('dryrun')

Check warning on line 74 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L74

Added line #L74 was not covered by tests

handler = LocalAssetHandler()

Check warning on line 76 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L76

Added line #L76 was not covered by tests

logger.info("Retrieving all assets with some files")

Check warning on line 78 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L78

Added line #L78 was not covered by tests

for asset in LocalAsset.objects.iterator():
logger.info(f"processing asset: {asset.title}")

Check warning on line 81 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L81

Added line #L81 was not covered by tests

source = os.path.dirname(asset.location[0])

Check warning on line 83 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L83

Added line #L83 was not covered by tests

if dryrun:
logger.info(f"Files found: {asset.location}")
continue

Check warning on line 87 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L86-L87

Added lines #L86 - L87 were not covered by tests

if settings.ASSETS_ROOT in source:
logger.info("The location is already the asset root, skipping...")
continue

Check warning on line 91 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L90-L91

Added lines #L90 - L91 were not covered by tests

if not os.path.exists(source):
logger.warning("Source path of the file for Asset does not exists, skipping...")
continue

Check warning on line 95 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L94-L95

Added lines #L94 - L95 were not covered by tests

try:

Check warning on line 97 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L97

Added line #L97 was not covered by tests

logger.info("Moving file to the asset folder")

Check warning on line 99 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L99

Added line #L99 was not covered by tests

dest = shutil.move(source, handler._create_asset_dir())

Check warning on line 101 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L101

Added line #L101 was not covered by tests

logger.info("Fixing perms")

Check warning on line 103 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L103

Added line #L103 was not covered by tests
if settings.FILE_UPLOAD_DIRECTORY_PERMISSIONS is not None:
os.chmod(os.path.dirname(dest), settings.FILE_UPLOAD_DIRECTORY_PERMISSIONS)

Check warning on line 105 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L105

Added line #L105 was not covered by tests

if settings.FILE_UPLOAD_PERMISSIONS is not None:
os.chmod(dest, settings.FILE_UPLOAD_PERMISSIONS)

Check warning on line 108 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L108

Added line #L108 was not covered by tests

except Exception as e:
logger.error(e)
continue

Check warning on line 112 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L110-L112

Added lines #L110 - L112 were not covered by tests

logger.info("Updating location field with new folder value")

Check warning on line 114 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L114

Added line #L114 was not covered by tests

asset.location = [x.replace(source, dest) for x in asset.location]
asset.save()

Check warning on line 117 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L117

Added line #L117 was not covered by tests

logger.info("Checking if geoserver should be updated")
asset_obj = asset.link_set.values_list('resource', flat=True).first()

Check warning on line 120 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L119-L120

Added lines #L119 - L120 were not covered by tests
if not asset_obj:
logger.warning("No resources connected to the asset, skipping resource update...")
continue
resource = ResourceBase.objects.get(pk=asset_obj)

Check warning on line 124 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L122-L124

Added lines #L122 - L124 were not covered by tests
if resource.subtype == 'raster':
logger.info("Updating GeoServer value")

Check warning on line 126 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L126

Added line #L126 was not covered by tests

store_to_update = gs_catalog.get_layer(resource.get_real_instance().alternate)\

Check warning on line 128 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L128

Added line #L128 was not covered by tests
.resource\
.store

raster_file = [x for x in asset.location if os.path.basename(x).split('.')[-1] in ["tiff", "tif", "geotiff", "geotif"]]
store_to_update.url = f"file:{raster_file[0]}"
try:
gs_catalog.save(store_to_update)
except Exception:
logger.error(f"Error during GeoServer update for resource {resource}, please check GeoServer logs")
logger.info("Geoserver Updated")

Check warning on line 138 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L133-L138

Added lines #L133 - L138 were not covered by tests

logger.info("Migration completed")

Check warning on line 140 in geonode/assets/management/commands/migrate_file_to_assets.py

View check run for this annotation

Codecov / codecov/patch

geonode/assets/management/commands/migrate_file_to_assets.py#L140

Added line #L140 was not covered by tests
Loading