[Django] #25346: collectstatic --clear doesn't delete broken symlinks from the STATIC_ROOT

9 views
Skip to first unread message

Django

unread,
Sep 3, 2015, 2:33:10 PM9/3/15
to django-...@googlegroups.com
#25346: collectstatic --clear doesn't delete broken symlinks from the STATIC_ROOT
-------------------------------------+--------------------
Reporter: ezheidtmann | Owner: nobody
Type: Uncategorized | Status: new
Component: contrib.staticfiles | Version: 1.8
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+--------------------
In my STATIC_ROOT, I have a directory containing some broken symlinks.

I run ./manage.py collectstatic -l -c

I see "Deleting '...'" for each of the broken symlinks, and no
corresponding "Linking '...'" lines. I would expect the broken symlinks to
be gone. But they still exist.

Steps to reproduce:

{{{
ln -s asdfasd_something_that_doesnt_exist_fasdfasdf
$STATIC_ROOT/broken_symlink
ls -l $STATIC_ROOT/broken_symlink
./manage.py collectstatic -l -c --noinput | grep broken_symlink
ls -l $STATIC_ROOT/broken_symlink
}}}

How could the broken symlinks get there in the first place? I'm using
collectstatic -l and I deleted the original static files from my app.

(Why do I care? Because this causes real trouble when used with
WhiteNoise, because it can't find the original file and fails to start)

--
Ticket URL: <https://code.djangoproject.com/ticket/25346>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Sep 3, 2015, 3:16:29 PM9/3/15
to django-...@googlegroups.com
#25346: collectstatic --clear doesn't delete broken symlinks from the STATIC_ROOT
-------------------------------------+-------------------------------------

Reporter: ezheidtmann | Owner: nobody
Type: Uncategorized | Status: new
Component: contrib.staticfiles | Version: 1.8
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by ezheidtmann):

* needs_docs: => 0
* needs_tests: => 0
* needs_better_patch: => 0


Old description:

> In my STATIC_ROOT, I have a directory containing some broken symlinks.
>
> I run ./manage.py collectstatic -l -c
>
> I see "Deleting '...'" for each of the broken symlinks, and no
> corresponding "Linking '...'" lines. I would expect the broken symlinks
> to be gone. But they still exist.
>
> Steps to reproduce:
>
> {{{
> ln -s asdfasd_something_that_doesnt_exist_fasdfasdf
> $STATIC_ROOT/broken_symlink
> ls -l $STATIC_ROOT/broken_symlink
> ./manage.py collectstatic -l -c --noinput | grep broken_symlink
> ls -l $STATIC_ROOT/broken_symlink
> }}}
>
> How could the broken symlinks get there in the first place? I'm using
> collectstatic -l and I deleted the original static files from my app.
>
> (Why do I care? Because this causes real trouble when used with
> WhiteNoise, because it can't find the original file and fails to start)

New description:

In my STATIC_ROOT, I have a directory containing some broken symlinks.

I run ./manage.py collectstatic -l -c

I see "Deleting '...'" for each of the broken symlinks, and no
corresponding "Linking '...'" lines. I would expect the broken symlinks to
be gone. But they still exist.

Steps to reproduce:

{{{
ln -s asdfasd_something_that_doesnt_exist_fasdfasdf
$STATIC_ROOT/broken_symlink
ls -l $STATIC_ROOT/broken_symlink
./manage.py collectstatic -l -c --noinput | grep broken_symlink
ls -l $STATIC_ROOT/broken_symlink
}}}

How could the broken symlinks get there in the first place? Answer: I'm


using collectstatic -l and I deleted the original static files from my

app, so the symlinks made last time still exist.

(Why do I care? Answer: this causes real trouble when used with


WhiteNoise, because it can't find the original file and fails to start)

--

--
Ticket URL: <https://code.djangoproject.com/ticket/25346#comment:1>

Django

unread,
Sep 8, 2015, 9:43:21 AM9/8/15
to django-...@googlegroups.com
#25346: collectstatic --clear doesn't delete broken symlinks from the STATIC_ROOT
--------------------------------------+------------------------------------
Reporter: ezheidtmann | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: contrib.staticfiles | Version: 1.8
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by timgraham):

* type: Uncategorized => Cleanup/optimization
* stage: Unreviewed => Accepted


Comment:

The cause seems to be that `FileSystemStorage.delete()`
[https://github.com/django/django/blob/1bbca7961cee20c4ddd453a7d74d316e84f4bbb5/django/core/files/storage.py#L286-L291
checks if the path exists] before trying to remove the file (for a broken
symlink, this returns False) . If we can't find an elegant solution, we
could document the behavior.

--
Ticket URL: <https://code.djangoproject.com/ticket/25346#comment:2>

Django

unread,
Sep 9, 2015, 3:09:07 AM9/9/15
to django-...@googlegroups.com
#25346: collectstatic --clear doesn't delete broken symlinks from the STATIC_ROOT
--------------------------------------+------------------------------------
Reporter: ezheidtmann | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: contrib.staticfiles | Version: 1.8

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by claudep):

Additionally to `os.path.exists`, I think we should also try
`os.lstat(path)` which returns a stat_result content for a broken symlink
(or OSError if the path doesn't exist at all).

--
Ticket URL: <https://code.djangoproject.com/ticket/25346#comment:3>

Django

unread,
Oct 12, 2015, 6:22:16 AM10/12/15
to django-...@googlegroups.com
#25346: collectstatic --clear doesn't delete broken symlinks from the STATIC_ROOT
--------------------------------------+------------------------------------
Reporter: ezheidtmann | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: contrib.staticfiles | Version: 1.8

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by ymyzk):

I sent a pull request: https://github.com/django/django/pull/5425
Please review it.

--
Ticket URL: <https://code.djangoproject.com/ticket/25346#comment:4>

Django

unread,
Oct 17, 2015, 2:14:18 PM10/17/15
to django-...@googlegroups.com
#25346: collectstatic --clear doesn't delete broken symlinks from the STATIC_ROOT
--------------------------------------+------------------------------------
Reporter: ezheidtmann | Owner: nobody
Type: Cleanup/optimization | Status: closed
Component: contrib.staticfiles | Version: 1.8
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by Tim Graham <timograham@…>):

* status: new => closed
* resolution: => fixed


Comment:

In [changeset:"0922bbf18d3ae8f37e1823df2dbc270d33334548" 0922bbf1]:
{{{
#!CommitTicketReference repository=""
revision="0922bbf18d3ae8f37e1823df2dbc270d33334548"
Fixed #25346 -- Allowed collectstatic to delete broken symlinks.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25346#comment:5>

Django

unread,
Oct 17, 2015, 2:43:11 PM10/17/15
to django-...@googlegroups.com
#25346: collectstatic --clear doesn't delete broken symlinks from the STATIC_ROOT
--------------------------------------+------------------------------------
Reporter: ezheidtmann | Owner: nobody
Type: Cleanup/optimization | Status: closed
Component: contrib.staticfiles | Version: 1.8

Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by Tim Graham <timograham@…>):

In [changeset:"9039ff60e3f9848338d3fbc6957f9e25e9edc22b" 9039ff60]:
{{{
#!CommitTicketReference repository=""
revision="9039ff60e3f9848338d3fbc6957f9e25e9edc22b"
[1.9.x] Fixed #25346 -- Allowed collectstatic to delete broken symlinks.

Backport of 0922bbf18d3ae8f37e1823df2dbc270d33334548 from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25346#comment:6>

Reply all
Reply to author
Forward
0 new messages