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

fix: keep the ftp dir in sync when the datatracker creates artifacts #8401

Merged
merged 7 commits into from
Jan 9, 2025
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
14 changes: 11 additions & 3 deletions ietf/doc/tests_conflict_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import io
import os
from pathlib import Path

from pyquery import PyQuery
from textwrap import wrap
Expand Down Expand Up @@ -387,7 +388,7 @@ def setUp(self):


class ConflictReviewSubmitTests(TestCase):
settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['CONFLICT_REVIEW_PATH']
settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['CONFLICT_REVIEW_PATH','FTP_PATH']
def test_initial_submission(self):
doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission')
url = urlreverse('ietf.doc.views_conflict_review.submit',kwargs=dict(name=doc.name))
Expand All @@ -403,16 +404,23 @@ def test_initial_submission(self):
# Right now, nothing to test - we let people put whatever the web browser will let them put into that textbox

# sane post using textbox
path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.name, doc.rev))
basename = f"{doc.name}-{doc.rev}.txt"
path = Path(settings.CONFLICT_REVIEW_PATH) / basename
ftp_dir = Path(settings.FTP_DIR) / "conflict-reviews"
if not ftp_dir.exists():
ftp_dir.mkdir()
ftp_path = ftp_dir / basename
self.assertEqual(doc.rev,'00')
self.assertFalse(os.path.exists(path))
self.assertFalse(path.exists())
self.assertFalse(ftp_path.exists())
r = self.client.post(url,dict(content="Some initial review text\n",submit_response="1"))
self.assertEqual(r.status_code,302)
doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission')
self.assertEqual(doc.rev,'00')
with io.open(path) as f:
self.assertEqual(f.read(),"Some initial review text\n")
f.close()
self.assertTrue(ftp_path.exists())
self.assertTrue( "submission-00" in doc.latest_event(NewRevisionDocEvent).desc)

def test_subsequent_submission(self):
Expand Down
13 changes: 11 additions & 2 deletions ietf/doc/tests_material.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@


class GroupMaterialTests(TestCase):
settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['AGENDA_PATH']
settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['AGENDA_PATH', 'FTP_DIR']
def setUp(self):
super().setUp()
self.materials_dir = self.tempdir("materials")
Expand All @@ -37,6 +37,10 @@ def setUp(self):
self.slides_dir.mkdir()
self.saved_document_path_pattern = settings.DOCUMENT_PATH_PATTERN
settings.DOCUMENT_PATH_PATTERN = self.materials_dir + "/{doc.type_id}/"
self.assertTrue(Path(settings.FTP_DIR).exists())
ftp_slides_dir = Path(settings.FTP_DIR) / "slides"
if not ftp_slides_dir.exists():
ftp_slides_dir.mkdir()

self.meeting_slides_dir = Path(settings.AGENDA_PATH) / "42" / "slides"
if not self.meeting_slides_dir.exists():
Expand Down Expand Up @@ -112,7 +116,12 @@ def test_upload_slides(self):
self.assertEqual(doc.title, "Test File - with fancy title")
self.assertEqual(doc.get_state_slug(), "active")

with io.open(os.path.join(self.materials_dir, "slides", doc.name + "-" + doc.rev + ".pdf")) as f:
basename=f"{doc.name}-{doc.rev}.pdf"
filepath=Path(self.materials_dir) / "slides" / basename
with filepath.open() as f:
self.assertEqual(f.read(), content)
ftp_filepath=Path(settings.FTP_DIR) / "slides" / basename
with ftp_filepath.open() as f:
self.assertEqual(f.read(), content)

# check that posting same name is prevented
Expand Down
17 changes: 13 additions & 4 deletions ietf/doc/tests_status_change.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import io
import os
from pathlib import Path

import debug # pyflakes:ignore

Expand Down Expand Up @@ -540,7 +541,7 @@ def setUp(self):
DocumentFactory(type_id='statchg',name='status-change-imaginary-mid-review',notify='notify@example.org')

class StatusChangeSubmitTests(TestCase):
settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['STATUS_CHANGE_PATH']
settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['STATUS_CHANGE_PATH', 'FTP_PATH']
def test_initial_submission(self):
doc = Document.objects.get(name='status-change-imaginary-mid-review')
url = urlreverse('ietf.doc.views_status_change.submit',kwargs=dict(name=doc.name))
Expand All @@ -556,14 +557,19 @@ def test_initial_submission(self):
# Right now, nothing to test - we let people put whatever the web browser will let them put into that textbox

# sane post using textbox
path = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.name, doc.rev))
self.assertEqual(doc.rev,'00')
self.assertFalse(os.path.exists(path))
basename = f"{doc.name}-{doc.rev}.txt"
filepath = Path(settings.STATUS_CHANGE_PATH) / basename
ftp_filepath = Path(settings.FTP_DIR) / "status-changes" / basename
self.assertFalse(filepath.exists())
self.assertFalse(ftp_filepath.exists())
r = self.client.post(url,dict(content="Some initial review text\n",submit_response="1"))
self.assertEqual(r.status_code,302)
doc = Document.objects.get(name='status-change-imaginary-mid-review')
self.assertEqual(doc.rev,'00')
with io.open(path) as f:
with filepath.open() as f:
self.assertEqual(f.read(),"Some initial review text\n")
with ftp_filepath.open() as f:
self.assertEqual(f.read(),"Some initial review text\n")
self.assertTrue( "mid-review-00" in doc.latest_event(NewRevisionDocEvent).desc)

Expand Down Expand Up @@ -628,3 +634,6 @@ def test_subsequent_submission(self):
def setUp(self):
super().setUp()
DocumentFactory(type_id='statchg',name='status-change-imaginary-mid-review',notify='notify@example.org')
ftp_subdir=Path(settings.FTP_DIR)/"status-changes"
if not ftp_subdir.exists():
ftp_subdir.mkdir()
6 changes: 3 additions & 3 deletions ietf/doc/utils_charter.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ def fix_charter_revision_after_approval(charter, by):
)
try:
os.link(new, ftp_filepath)
except IOError:
except IOError as ex:
log(
"There was an error creating a harlink at %s pointing to %s"
% (ftp_filepath, new)
"There was an error creating a hardlink at %s pointing to %s: %s"
% (ftp_filepath, new, ex)
)

events = []
Expand Down
14 changes: 12 additions & 2 deletions ietf/doc/views_conflict_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import datetime
import io
import os
from pathlib import Path

from django import forms
from django.shortcuts import render, get_object_or_404, redirect
Expand Down Expand Up @@ -181,12 +182,21 @@ def clean_txt(self):
return get_cleaned_text_file_content(self.cleaned_data["txt"])

def save(self, review):
filename = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (review.name, review.rev))
with io.open(filename, 'w', encoding='utf-8') as destination:
basename = f"{review.name}-{review.rev}.txt"
filepath = Path(settings.CONFLICT_REVIEW_PATH) / basename
with filepath.open('w', encoding='utf-8') as destination:
if self.cleaned_data['txt']:
destination.write(self.cleaned_data['txt'])
else:
destination.write(self.cleaned_data['content'])
ftp_filepath = Path(settings.FTP_DIR) / "conflict-reviews" / basename
try:
os.link(filepath, ftp_filepath) # Path.hardlink_to is not available until 3.10
except IOError as e:
log.log(
"There was an error creating a hardlink at %s pointing to %s: %s"
% (ftp_filepath, filepath, e)
)

#This is very close to submit on charter - can we get better reuse?
@role_required('Area Director','Secretariat')
Expand Down
16 changes: 14 additions & 2 deletions ietf/doc/views_material.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@


# views for managing group materials (slides, ...)
import io
import os
from pathlib import Path
import re

from django import forms
Expand Down Expand Up @@ -162,9 +162,21 @@ def edit_material(request, name=None, acronym=None, action=None, doc_type=None):
f = form.cleaned_data["material"]
file_ext = os.path.splitext(f.name)[1]

with io.open(os.path.join(doc.get_file_path(), doc.name + "-" + doc.rev + file_ext), 'wb+') as dest:
basename = f"{doc.name}-{doc.rev}{file_ext}" # Note the lack of a . before file_ext - see os.path.splitext
filepath = Path(doc.get_file_path()) / basename
with filepath.open('wb+') as dest:
for chunk in f.chunks():
dest.write(chunk)
if not doc.meeting_related():
log.assertion('doc.type_id == "slides"')
ftp_filepath = Path(settings.FTP_DIR) / doc.type_id / basename
try:
os.link(filepath, ftp_filepath) # Path.hardlink is not available until 3.10
except IOError as ex:
log.log(
"There was an error creating a hardlink at %s pointing to %s: %s"
% (ftp_filepath, filepath, ex)
)

if prev_rev != doc.rev:
e = NewRevisionDocEvent(type="new_revision", doc=doc, rev=doc.rev)
Expand Down
23 changes: 17 additions & 6 deletions ietf/doc/views_status_change.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import datetime
import io
import os
from pathlib import Path
import re

from typing import Dict # pyflakes:ignore
Expand Down Expand Up @@ -33,6 +34,7 @@
from ietf.mailtrigger.utils import gather_address_lists
from ietf.name.models import DocRelationshipName, StdLevelName
from ietf.person.models import Person
from ietf.utils.log import log
from ietf.utils.mail import send_mail_preformatted
from ietf.utils.textupload import get_cleaned_text_file_content
from ietf.utils.timezone import date_today, DEADLINE_TZINFO
Expand Down Expand Up @@ -154,12 +156,21 @@ def clean_txt(self):
return get_cleaned_text_file_content(self.cleaned_data["txt"])

def save(self, doc):
filename = os.path.join(settings.STATUS_CHANGE_PATH, '%s-%s.txt' % (doc.name, doc.rev))
with io.open(filename, 'w', encoding='utf-8') as destination:
if self.cleaned_data['txt']:
destination.write(self.cleaned_data['txt'])
else:
destination.write(self.cleaned_data['content'])
basename = f"{doc.name}-{doc.rev}.txt"
filename = Path(settings.STATUS_CHANGE_PATH) / basename
with io.open(filename, 'w', encoding='utf-8') as destination:
if self.cleaned_data['txt']:
destination.write(self.cleaned_data['txt'])
else:
destination.write(self.cleaned_data['content'])
try:
ftp_filename = Path(settings.FTP_DIR) / "status-changes" / basename
os.link(filename, ftp_filename) # Path.hardlink is not available until 3.10
except IOError as ex:
log(
"There was an error creating a hardlink at %s pointing to %s: %s"
% (ftp_filename, filename, ex)
)

#This is very close to submit on charter - can we get better reuse?
@role_required('Area Director','Secretariat')
Expand Down
10 changes: 10 additions & 0 deletions ietf/submit/checkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import io
import os
from pathlib import Path
import re
import shutil
import sys
Expand Down Expand Up @@ -280,6 +281,15 @@ def check_file_txt(self, path):

dest = os.path.join(settings.SUBMIT_YANG_DRAFT_MODEL_DIR, model)
shutil.move(path, dest)
ftp_dest = Path(settings.FTP_DIR) / "yang" / "draftmod" / model
try:
os.link(dest, ftp_dest)
except IOError as ex:
log(
"There was an error creating a hardlink at %s pointing to %s: %s"
% (ftp_dest, dest, ex)
)


# summary result
results.append({
Expand Down
4 changes: 4 additions & 0 deletions ietf/submit/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
import pathlib
import re
import subprocess
import sys
import time
import traceback
Expand Down Expand Up @@ -1596,3 +1597,6 @@ def active(dirent):
modfile.unlink()
except UnicodeDecodeError as e:
log.log(f"Error processing {item.name}: {e}")

ftp_moddir = Path(settings.FTP_DIR) / "yang" / "draftmod"
subprocess.call(("/usr/bin/rsync", "-aq", "--delete", moddir, ftp_moddir))
Loading