In production, we use settings.DEFAULT_FROM_EMAIL as our primary source
of from_email, rather than settings.SUBMIT_EMAIL_FROM
Default to DEFAULT_FROM_EMAIL if it is not Null, fall back to SUBMIT_EMAIL_FROM
The real consumer (in production) is a Celery task in layerindex/tasks.py
@tasks.task
def send_email(subject, text_content, from_email=settings.DEFAULT_FROM_EMAIL, to_emails=[]):
Signed-off-by: Tim Orling <tim.orling@konsulko.com>
Since commits:
bitbake f33ce7e7
'BBHandler/cooker: Implement recipe and global classes'
oe-core f5c12800
'classes: Update classes to match new bitbake class scope functionality'
we now have a lot of the oe-core recipe classes in meta/classes-recipe.
We are also missing any bbclasses in meta/classes-global
[YOCTO #15238]
Signed-off-by: Tim Orling <tim.orling@konsulko.com>
Since we are only using parse_version for comparison (typically checking
that we are greater than some minimum version for tool or package), one
would think we can use packaging.version.parse as if it was parse_version
Unfortunately, this requires conforming to PEP-440 version definitions,
which does not work for e.g. autotools (2.72d) nor older openssl (1.1.1p).
We rely in these (and to be sure other) cases on the LegacyVersion behavior.
https://packaging.python.org/en/latest/specifications/version-specifiers/#summary-of-differences-from-pkg-resources-parse-version
"This specification purposely restricts the syntax which constitutes a
valid version while pkg_resources.parse_version attempts to provide some
meaning from any arbitrary string."
In order to have the least impact to the overall code, we instead add
packaging_legacy to requirements.txt and use packaging_legacy.version.parse
as if it was parse_version.
https://pypi.org/project/packaging-legacy/https://github.com/pypa/packaging/pull/407
Since pypi.org itself is depending on packaging_legacy (in fact, a pypi dev
developed the package), we can expect it to be supported for quite some time.
https://github.com/pypi/warehouse/pull/13500
[YOCTO #15348]
Signed-off-by: Tim Orling <tim.orling@konsulko.com>
* Add an "Update Layer" button to the layer detail view.
- This allows a user that is a member of is_staff to trigger
an update of the current layer (for the current branch)
* Add an "Update Layer" button to the reviewdetail view
- This allows a user that is a member of is_staff and has
publish_layer permissions to trigger an update attempt
of the layer under review (even in the un-published state)
* The update is run as a task with Celery
NOTE:
You must have the RABBITMQ_ and DATABASE_ credentials set
correctly in the docker/settings.py file or set via
environment variables or you will get authentication errors
talking to layersdb or layersrabbit containers.
[YOCTO #12484]
layerindex/views.py: add update_layer_view
layerindex/urls.py: add update_layer_view
layerindex/urls_branch.py: add update_layer_view
templates/layerindex/reviewdetail.html: add Update Layer button
templates/layerindex/detail.html: add Update Layer button
templates/layerindex: add updatelayer.html
TODO:
While the update is happening, the AJAX rendering of the
update.log is showing the b'' characters and not adding
any new lines. If you go back to the same task view
afterwards, the log is rendered as expected.
TODO:
After the update is completed, it would be nice to have a
button to return you to the page from where you called the
"Update Layer".
Signed-off-by: Tim Orling <tim.orling@konsulko.com>
For layers which do not follow standard branch names (including
the inclusive naming move away from "master" to "main") we have
the actual_branch field set in a LayerBranch object. Previously
this was only exposed via the admin interface.
Allow layer maintainers (including upon submitting a new layer)
to set the 'Actual branch' in the web UI.
Add a check to make sure the actual_branch is a valid branch
name using 'git check-ref-format --branch <actual_branch>'
since we are not using full refs.
[YOCTO #8008]
NOTE:
Only existing LayerBranches will be editable. A new layer
can be submitted with a different branch for "master", but
only the "master" LayerBranch will be created.
Further changes to the update.py script will be needed to
make creation of new stable branches with an actual_branch
possible.
Signed-off-by: Tim Orling <tim.orling@konsulko.com>
The Branch Comparison view would throw an error because of a parser_view instead of parse_view typo.
[YOCTO #15332]
Signed-off-by: Tim Orling <tim.orling@konsulko.com>
I noticed in the branch comparison plain text view ("Plain text" button
in the Tools -> Branch Comparison page) that in current versions of
Firefox the ellipses were coming through corrupted, though they looked
fine in the HTML version, and it turns out this is because I wasn't
specifying a character set encoding. It should be UTF-8, so add a
charset to the content type stating as such for this and other similar
views.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.microsoft.com>
Added SPDX identifiers to all .py files except those in migrations directory.
Fixes: [YOCTO #13527]
Signed-off-by: Meh Mbeh Ida Delphine <idadelm@gmail.com>
Signed-off-by: Paul Eggleton <bluelightning@bluelightning.org>
Removed all obsolete references to django.core.urlresolvers. Added the
newly required on_delete fields to foreign key relationships in models.py
and in all migrations.
Signed-off-by: Amber Elliot <amber.n.elliot@intel.com>
Signed-off-by: Paul Eggleton <bluelightning@bluelightning.org>
Reloading an existing update task page was taking an extremely long time
to fetch down the task log and then pegging the client CPU such that the
browser gave a warning. Digging into it, logs from a Clear Linux update
task can be of the order of 500MB in size (with all of the line
refreshing using CRs that happens during downloads), causing (a) the
transfer to take a long time and (b) the JS code that updates the log
text box to be extremely busy. If we're loading the entire log from
scratch (as we are when we refresh the page) rather than just getting an
update since the last poll, we don't need any of those line refreshes -
so squash them out before returning the data.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
When using the layer: advanced query term, if you want to match on
OE-Core, its actual layer name is "openembedded-core", but people will
naturally assume that "oe-core" should work, so make it so (case
insensitive).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Allow filtering only on recipe name - i.e., searching for "git" finds
any recipe with "git" in the name or description. Now, you can search
for "pn:git" which will return only recipes with the name "git".
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Use shlex.split() to split the query string so that quotes can be used
to delimit strings containing spaces to be matched as a whole. This
worked with the previous code, but it did not support single quotes -
these caused an error in Django's filter code and thus an internal
server error (as did querying for ""). Add some additional checks for
single quotes as it is still possible to get them past shlex.split()
e.g. with something like "'hello'" (with quotes).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Add an extra tool that lets you view all of the recipe dependencies in
a layer. There is also a mode that shows only cross-layer dependencies,
which can be useful to find dependencies on recipes in other layers
that aren't declared in the layer's dependencies (or conversely where a
layer dependency is no longer necessary).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Add the ability to compare available recipes and their versions between
two branches for a selection of layers (default is just OE-Core). This
was mainly intended to help us with the Yocto Project release notes
preparation (hence the "Plain text" button at the bottom of the page)
but is also useful in its own right.
Note: for readability, SRCREVs are only shown when PV has not changed.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
* Tweak message when one or more (but not all) security question answers
have been changed so that it's clear that all are required
* Ensure success message gets shown upon saving
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
When running a task (e.g. importing other distribution data), the web
frontend polls to get task output every second. In the view handling
this request we check to see if the underlying Celery task is finished
by getting the AsyncResult and then calling result.ready().
Unfortunately that latter call seems to be failing some of the time in
the development Docker setup that I am using, throwing a
ConnectionResetError. Because the polling is regular it doesn't really
matter if this fails as there'll be another chance on the next poll, so
just allow the call to fail silently. (It pains me to put in workarounds
like this but at the moment I can't determine the real cause of the
issue, and this stops the stream of ultimately useless error report
emails that I'm getting as an admin of the development instance).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If an update task's output contains a single quote for example (') then
this will be escaped to an HTML entity before it gets sent as a
response. However, that means that the length of the data in the response
will be greater than the length of the original data, resulting in
characters getting missed out when we read the next chunk - so we
can't use the escaped length to set the next position to read from. The
easiest thing to do is have the Django view send us the actual position
we're at and then we don't have to try to calculate it on the JS side.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Add the ability to mark each patch with a disposition indicating whether
the patch is interesting or not.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Editing on this page is done by clicking through to another page, so
it should be a DetailView rather than an UpdateView and shouldn't have a
form class set.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
It's best practice for security reasons to use shell=False and pass
command line arguments as a list; it also avoids some pain with
escaping, so let's use it everywhere we can (in fact we're only left
with one place in layerindex/tasks.py where we now pass shell=True).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Add user security questions upon registration as extra authentication
for password reset. Three unique security questions must be chosen and
answered. Answers are then stored in the database with the same hashing
algorithm as the users's password.
On password reset, users get two chances to get two out of three
security questions answered correctly. After a second failure their
account is locked and email is sent to the admin. The same template is
shown for the axes lockout. Super user cannot reset their password until
they set security questions.
Users can update their security questions or add them if they weren't
originally set (in the case of super user) in Edit Profile.
Signed-off-by: Amber Elliot <amber.n.elliot@intel.com>
This involves changing how registration templates are referenced
and how the activation email is sent on user's email address change.
Signed-off-by: Amber Elliot <amber.n.elliot@intel.com>
Best practices state that you should use a mechanism that ensures files
get closed in case of any error, so let's do that.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Add links to the same recipe in other branches in the recipe detail page
(and RRS recipe detail page) so that you can see which versions are
available in other branches and drill down to the detail if you want to.
Implements [YOCTO #13019].
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If someone adds you as a maintainer of a layer as a matter of courtesy
it would be nice if you get an email.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Use a parameter to pass the current page to the Edit Profile URL so that
saving or cancelling returns you to that same page.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If you're searching for items that are of status "unknown/not available"
in the other distro packages, you're usually doing so to find things
that haven't been dispositioned. Originally I had included them here
because the "available" status correctly excludes items with the
"distro-specific" status and "unknown/not available" seemed like it
should be the inverse, but usage seems to require that it not be.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If a user goes to Edit Profile and changes their email address,
deactivate their account temporarily and make them go through the
registration process to confirm that the new email address is in fact
valid and theirs.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Users may want to change their usernames for a number of different
reasons, but at the moment we require them to contact an admin to do
that. Provided we validate the new username correctly and add a CAPTCHA
to make automated enumeration difficult, we can add username to the Edit
Profile form and then users can do that any time they wish.
While we're doing this, show a message when the profile is successfully
updated.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This was copy-pasted from the DistroSearchView and I clearly forgot to
replace the reference here.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
nvd3 and its python/django wrappers appear to be no longer actively
maintained, and at least the wrappers were a bit clunky to use. Looking
around for a suitable replacement, Chart.js seems capable, has no
additional dependencies and is fairly simple to use. As a bonus we get
to drop a few Python dependencies from our list.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
It's not too common but there are instances where people have copied
.inc files into their own layer and modified them, and if you are using
such a layer that could result in unexpected behaviour. In order to get
a handle on when this is being done, collect data about all .inc files
and show duplicates in the Duplicates screen.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Split out the code used in the recipe search views to its own function
and use that same function in three different places rather than having
a copy of largely the same code. Also take the opportunity to add some
comments.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
On layers.openembedded.org we're seeing requests from some search engine
crawlers requesting the CSV export URL with an invalid branch for the
layer. I couldn't see the referer anywhere in the logs but I suspect it
has to do with some recent cleanup work I did in the database where I
deleted some invalid LayerBranch records - they were probably following
links in a cached version of the webpage. In any event we want to return
404 in this situation rather than an internal server error.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
In order to show bbappends on the recipe detail page we are doing a
regex query to find any whose names match up with the recipe. In the
layer index instance at layers.openembedded.org viewing the recipe
detail page for any recipe whose name contains ++ (e.g. libsigc++-2.0 in
meta-oe) results in an invalid regex and causes a database error. Escape
any + signs in the name used within the regex in order to fix this.
(I wasn't actually able to reproduce this on my own setup despite also
using MariaDB, but I did find that the unescaped query was not correctly
matching records so it needed to be fixed anyway.)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
When you make changes to the infrastructure it can be useful to test
that email sending is working, since for that to work that involves the
code, Celery, RabbitMQ and SMTP being functional. However, up until now
to run a test you needed to submit a fake layer which is a bit annoying.
Add an explicit "Test email" option to the Tools drop-down for staff
users to allow them to send an email to themselves.
Note: the page will come back when the Celery job has been created, it
does not check and report on the job status - you need to look on the
server side to see that.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
For situations where the user launches a distro comparison update
process and then shortly afterwards realises it is operating with the
wrong configuration (or is otherwise broken) and is going to take a long
time to finish, add a button to the task page to stop the task. This was
tricky to get working, since the default behaviour of Celery's revoke()
would either terminate both the Celery task process along with the update
process (leaving us with no log saved to the database) or worse not even
kill the update process, depending on the signal sent. To avoid this,
send SIGUSR2, trap it in the task process and kill the child process,
returning gracefully. To make that possible I had to rewrite runcmd() to
use subprocess.Popen() instead of subprocess.check_call() as otherwise
we can't get the child's PID.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If a distro comparison update task fails (returning a non-zero value to
indicate as such) we were not able to see this easily from the frontend.
Show success/failure in the form of a label on the task page and general
update list/detail, and if the task fails while we're watching then make
the progress bar go red as well. Also make a distinction between the
process failing (retcode > 0) and being terminated (retcode < 0, e.g.
process was killed).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Provide a mechanism for distro comparison update tasks to display
progress. In practice this means the update command needs to write the
progress percentage to a file and then the log view (which is polled by
the frontend) reads this file. Originally I was going to use a FIFO for
this but that turned out to be a but unreliable; I also tried to use
Celery's state mechanism to pass it back but I simply could not get it
to work. The file-based mechanism is good enough though.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
We were refreshing the page constantly in order to show output while
a task was running, which basically worked but is horrible. Instead,
write the task output to a file and then use AJAX calls to request
whatever output has been written to the file since the last call
and call this roughly every second. Put the output in a scrollable <pre>
element instead of making it the length of the page, and auto-scroll
to the end (unless the user grabs the scrollbar and pulls it upwards -
it may not be immediately obvious that you can do this if there is a lot
of output since you have to pull it up when the scrolling animation is
not running, but it is possible).
An alternative would be to have used some kind of long-lived HTTP
session or a websocket, but those come with their own set of problems
so I elected to use this much simpler method.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If a user doesn't have publish rights and the type of the layer isn't
already "Base" then disallow selecting the Base layer type. Some
submitters are selecting this type for their own layers, but it's pretty
much reserved for openembedded-core and meta-oe (so that they appear at
the top of the layer list).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
When showing the error/warning counts for update records we need to
include any errors/warnings that are shown only in the main update log,
so we need to adjust how these are collected. Use a function rather than
pure aggregation to give a bit more control, and a {% with ... %} block
in the template to avoid the functions being called more than necessary.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Make layerupdate collection slightly more reliable and make it easier
to see when updates have actually been captured:
* Split layerbranch into separate layer and branch fields, since there
may not be a layerbranch in existence but we might want to log an
error relating to the branch and layer.
* Show all layerupdates on the update detail page, not just those with
log messages
* Record before and after revisions and show these in the update detail
and layerupdate detail (with links)
* Record return code of update_layer process
* Highlight layer updates with a non-zero return code, errors or
warnings in the output on the update detail page
* Show duration on the layerupdate detail page
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
On the recipe detail page we provide a link to the actual recipe file
for reference purposes. However, for recipes that include a common .inc
file, many of the definitions of variable values will be inside the
.inc, therefore if you just look at the recipe you won't see the full
picture. Of course you can just go up to the parent directory in the
repository web interface, but for convenience's sake add links to any
files that are included/required by the recipe that are adjacent to
the recipe itself. (We already have the data in the form of the
RecipeFileDependency records that are intended to ensure we know when
the recipe needs to be updated if one of the files it includes changes).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>