Skip to content

Commit

Permalink
Introduce registries selection
Browse files Browse the repository at this point in the history
  • Loading branch information
marusak committed Jul 27, 2020
1 parent 7e350d7 commit a6662db
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 19 deletions.
48 changes: 34 additions & 14 deletions src/ImageSearchModal.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import { ListGroup, ListGroupItem, Modal } from 'patternfly-react';
import { Button, InputGroup, InputGroupText } from '@patternfly/react-core';
import { SearchIcon } from '@patternfly/react-icons';
import { Button, InputGroup } from '@patternfly/react-core';

import * as Select from '../lib/cockpit-components-select.jsx';
import { ErrorNotification } from './Notification.jsx';
import cockpit from 'cockpit';
import rest from './rest.js';
Expand All @@ -22,6 +22,7 @@ export class ImageSearchModal extends React.Component {
searchInProgress: false,
searchFinished: false,
isSystem: props.systemServiceAvailable,
registry: "",
};
this.onDownloadClicked = this.onDownloadClicked.bind(this);
this.onItemSelected = this.onItemSelected.bind(this);
Expand Down Expand Up @@ -77,7 +78,7 @@ export class ImageSearchModal extends React.Component {
path: "/v1.12/libpod/images/search",
body: "",
params: {
term: this.state.imageIdentifier,
term: this.state.registry + this.state.imageIdentifier,
},
};
this.activeConnection.call(options)
Expand Down Expand Up @@ -136,17 +137,36 @@ export class ImageSearchModal extends React.Component {
</form>
}
<InputGroup>
<InputGroupText id="username" aria-label={_("Search")}>
<SearchIcon />
</InputGroupText>
<input id='search-image-dialog-name'
autoFocus
className='form-control'
type='text'
placeholder={_("Search by name or description")}
value={this.state.imageIdentifier}
onKeyPress={this.onKeyPress}
onChange={e => this.onValueChanged('imageIdentifier', e.target.value)} />
<div className="vertical-group">
<label htmlFor="registry-select">{_("Registry")}</label>
<Select.Select id='registry-select'
initial={this.state.registry}
onChange={value =>
this.setState({ registry: value }, () => this.onSearchTriggered(false))
}>
<Select.SelectEntry data="" key="all">
{_("All registries")}
</Select.SelectEntry>
{ (this.props.registries.search || []).map(r => {
const rx = r[r.length - 1] === "/" ? r : r + "/";
return <Select.SelectEntry data={rx} key={rx}>
{rx}
</Select.SelectEntry>;
})
}
</Select.Select>
</div>
<div className="vertical-group wide">
<label htmlFor="search-image-dialog-name">{_("Search Term")}</label>
<input id='search-image-dialog-name'
autoFocus
className='form-control'
type='text'
placeholder={_("Search by name or description")}
value={this.state.imageIdentifier}
onKeyPress={this.onKeyPress}
onChange={e => this.onValueChanged('imageIdentifier', e.target.value)} />
</div>
</InputGroup>

{this.state.searchInProgress && <div id='search-image-dialog-waiting' className='spinner' />}
Expand Down
1 change: 1 addition & 0 deletions src/Images.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ class Images extends React.Component {
close={() => this.setState({ showSearchImageModal: false })}
downloadImage={this.downloadImage}
user={this.props.user}
registries={this.props.registries}
userServiceAvailable={this.props.userServiceAvailable}
systemServiceAvailable={this.props.systemServiceAvailable} /> }
{this.state.imageDownloadInProgress && <div className='download-in-progress'> {_("Pulling")} {this.state.imageDownloadInProgress}... </div>}
Expand Down
7 changes: 6 additions & 1 deletion src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,11 @@ class Application extends React.Component {
init(system) {
client.getInfo(system)
.then(reply => {
this.setState({ [system ? "systemServiceAvailable" : "userServiceAvailable"]: true, version: reply.version.Version });
this.setState({
[system ? "systemServiceAvailable" : "userServiceAvailable"]: true,
version: reply.version.Version,
registries: reply.registries,
});
this.updateImagesAfterEvent(system);
this.updateContainersAfterEvent(system, true);
client.streamEvents(system,
Expand Down Expand Up @@ -514,6 +518,7 @@ class Application extends React.Component {
user={permission.user || _("user")}
userServiceAvailable={this.state.userServiceAvailable}
systemServiceAvailable={this.state.systemServiceAvailable}
registries={this.state.registries}
/>;
const containerList =
<Containers
Expand Down
24 changes: 24 additions & 0 deletions src/podman.scss
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,27 @@
padding-left: 30px;
}

.vertical-group {
position: relative;
display: flex;
align-items: baseline;
align-self: flex-end;
flex-direction: column;
margin: 1rem 0 0;
text-align: left;

> label,
> select,
> input {
display: block;
margin-right: var(--pf-global--spacer--md);
}
}

.vertical-group.wide {
flex-grow: 1;
}

.modal-body .alert {
margin-bottom: -20px;
margin-top: 30px;
Expand Down Expand Up @@ -236,3 +257,6 @@
font-weight: 400;
}

#registry-select option:first-child {
font-style: italic;
}
15 changes: 11 additions & 4 deletions test/check-application
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ from machine_core import ssh_connection

REGISTRIES_CONF="""
[registries.search]
registries = ['localhost:5000']
registries = ['localhost:5000', 'localhost:6000']
[registries.insecure]
registries = ['localhost:5000']
registries = ['localhost:5000', 'localhost:6000']
"""

def checkImage(browser, name, owner):
Expand Down Expand Up @@ -406,12 +406,14 @@ class TestApplication(testlib.MachineCase):
execute = self.execute

def prepare():
# Create and start registry container
# Create and start registry containers
self.execute(True, "podman run -d -p 5000:5000 --name registry registry:2")
self.execute(True, "podman run -d -p 6000:5000 --name registry_alt registry:2")
# Add local insecure registry into registries conf
self.execute(True, "echo \"{0}\" > /etc/containers/registries.conf && systemctl stop podman.service".format(REGISTRIES_CONF))
# Push busybox image to the local registry
# Push busybox image to the local registries
self.execute(True, "podman tag busybox localhost:5000/my-busybox && podman push localhost:5000/my-busybox")
self.execute(True, "podman tag busybox localhost:6000/my-busybox && podman push localhost:6000/my-busybox")
# Untag busybox image which duplicates the image we are about to download
self.execute(True, "podman rmi -f busybox")

Expand Down Expand Up @@ -504,6 +506,7 @@ class TestApplication(testlib.MachineCase):

self.login_and_go("/podman", authorized=True, superuser=True)
b.wait_present("#app")
testlib.sit()

dialog0 = DownloadImageDialog('my-busybox', user="system")
dialog0.openDialog() \
Expand Down Expand Up @@ -538,6 +541,10 @@ class TestApplication(testlib.MachineCase):
.selectImageAndDownload() \
.expectDownloadErrorForNonExistingTag()

# Test registries
# TODO Check that the list contains both repos
# TODO Check that it filters only in one

def testLifecycleOperationsUser(self):
self._testLifecycleOperations(False)

Expand Down

0 comments on commit a6662db

Please sign in to comment.