add pull command to information

fixes #9

also added `REGISTRY_PUBLIC_URL` variable for display in this command and in the footer
pull/12/head
Mike Heijmans 2016-05-18 10:30:23 -07:00
parent 688ac19223
commit 74004794b5
No known key found for this signature in database
GPG Key ID: AD75EF5BA031CA8B
7 changed files with 55 additions and 41 deletions

View File

@ -23,6 +23,7 @@ Available Environment Variables:
* **REGISTRY_PORT** - the port of the registry host (default: `5000`)
* **REGISTRY_PROTO** - the protocol to use (ie: `http` or `https`) (default: `https`)
* **REGISTRY_SSL_VERIFY** - should the certificate be verified if using SSL (default: `true`)
* **REGISTRY_PUBLIC_URL** - optional url to use for displaying in pull command and footer (default: `REGISTRY_HOST`:`REGISTRY_PORT`)
* **USERNAME** - setting this will activate BASIC AUTH and require this username
* **PASSWORD** - optional password for BASIC AUTH (you must set the `USERNAME` for this to work)

View File

@ -1,4 +1,5 @@
import React from 'react';
import axios from 'axios';
import Footer from './sections/Footer';
import Header from './sections/Header';
import Repos from './Repos';
@ -11,7 +12,8 @@ class RepoBrowser extends React.Component {
this.state = {
repo: undefined,
tag: undefined,
getinfo: false
getinfo: false,
registry: {}
}
}
@ -29,6 +31,25 @@ class RepoBrowser extends React.Component {
})
}
componentDidMount(){
this.getRegistryInfo()
.then(function(data){
this.setState({
registry: data
})
}.bind(this));
}
getRegistryInfo(){
return axios.get(`/registryinfo`)
.then(function (response) {
return(response.data);
})
.catch(function (response) {
console.log('ERROR IN AXIOS! ' + response);
});
};
render(){
return(
<div className="main-container">
@ -41,10 +62,10 @@ class RepoBrowser extends React.Component {
<Tags repo={this.state.repo} setTag={(name) => this.handleSetTag(name)}/>
</div>
<div className="col-sm-6 col-left-border">
<TagInfo tag={this.state.tag} repo={this.state.repo} getinfo={this.state.getinfo}/>
<TagInfo tag={this.state.tag} repo={this.state.repo} getinfo={this.state.getinfo} registry={this.state.registry}/>
</div>
</div>
<Footer />
<Footer registry={this.state.registry} />
</div>
)};
}

View File

@ -7,39 +7,43 @@ import RepoConfig from './RepoConfig';
require('react-datetime');
export default class RepoTagInfo extends React.Component {
render(){
console.log(this.props.registry)
return(
<div>
<div className="row">
<div className="col-md-3"><b>Architecture:</b></div>
<div className="col-md-7">{this.props.info.architecture}</div>
<div className="col-md-9">{this.props.info.architecture}</div>
</div>
<div className="row">
<div className="col-md-3"><b>OS:</b></div>
<div className="col-md-7">{this.props.info.information && this.props.info.information.os}</div>
<div className="col-md-9">{this.props.info.information && this.props.info.information.os}</div>
</div>
<div className="row">
<div className="col-md-3"><b>Created:</b></div>
<div className="col-md-7">
<div className="col-md-9">
{this.props.info.information && <Time value={this.props.info.information.created_millis} format="MM/DD/YYYY hh:mma" />} UTC
<span className='small text-muted'> ({this.props.info.information && <Time value={this.props.info.information.created_millis} titleFormat="YYYY/MM/DD HH:mm" relative />})</span></div>
</div>
<div className="row">
<div className="col-md-3"><b>Author:</b></div>
<div className="col-md-7">{this.props.info.information && this.props.info.information.author}</div>
<div className="col-md-9">{this.props.info.information && this.props.info.information.author}</div>
</div>
<div className="row">
<div className="col-md-3"><b>ID:</b></div>
<div className="col-md-7">{this.props.info.information && this.props.info.information.id}</div>
<div className="col-md-9">{this.props.info.information && this.props.info.information.id}</div>
</div>
<div className="row">
<div className="col-md-3"><b>Container:</b></div>
<div className="col-md-7">{this.props.info.information && this.props.info.information.container}</div>
<div className="col-md-9">{this.props.info.information && this.props.info.information.container}</div>
</div>
<div className="row">
<div className="col-md-3"><b>Docker Version:</b></div>
<div className="col-md-7">{this.props.info.information && this.props.info.information.docker_version}</div>
<div className="col-md-9">{this.props.info.information && this.props.info.information.docker_version}</div>
</div>
<div className="row">
<div className="col-md-3"><b>Pull Command:</b></div>
<div className="col-md-9">docker pull {this.props.registry.public_url}/{this.props.repo}:{this.props.tag}</div>
</div>
</div>
)
@ -47,5 +51,8 @@ export default class RepoTagInfo extends React.Component {
}
RepoTagInfo.propTypes = {
info: React.PropTypes.object.isRequired
info: React.PropTypes.object.isRequired,
registry: React.PropTypes.object.isRequired,
repo: React.PropTypes.string,
tag: React.PropTypes.string
}

View File

@ -66,7 +66,7 @@ export default class RepoTagInfo extends React.Component {
<div>
<Loader loaded={this.state.loaded} color="red" scale={0.75} >
{this.state.error && "Error Fetching Repos"}
{ this.state.info && <RepoInfo info={this.state.info} />}
{ this.state.info && <RepoInfo info={this.state.info} repo={this.state.repo} tag={this.state.tag} registry={this.props.registry}/>}
<div className="row">
<div className="col-md-12">
{this.state.info && <RepoConfig config={this.state.info.information.config} />}
@ -80,6 +80,7 @@ export default class RepoTagInfo extends React.Component {
RepoTagInfo.propTypes = {
getinfo: React.PropTypes.bool.isRequired,
registry: React.PropTypes.object.isRequired,
repo: React.PropTypes.string,
tag: React.PropTypes.string
}

View File

@ -7,7 +7,7 @@ class TagInfo extends React.Component {
return (
<div>
<h3>Information</h3>
<RepoTagInfo tag={this.props.tag} repo={this.props.repo} getinfo={this.props.getinfo}/>
<RepoTagInfo tag={this.props.tag} repo={this.props.repo} getinfo={this.props.getinfo} registry={this.props.registry}/>
</div>
);
}
@ -18,6 +18,7 @@ export default TagInfo;
TagInfo.propTypes = {
getinfo: React.PropTypes.bool.isRequired,
registry: React.PropTypes.object.isRequired,
tag: React.PropTypes.string,
repo: React.PropTypes.string
}

View File

@ -1,41 +1,15 @@
import React from 'react';
import axios from 'axios';
import { Navbar } from 'react-bootstrap';
export default class Footer extends React.Component {
constructor(props){
super(props);
this.state = {
registry: {}
}
}
getRegistryInfo(){
return axios.get(`/registryinfo`)
.then(function (response) {
return(response.data);
})
.catch(function (response) {
console.log('ERROR IN AXIOS! ' + response);
});
};
componentDidMount(){
this.getRegistryInfo()
.then(function(data){
this.setState({
registry: data
})
}.bind(this));
}
render() {
return (
<div className='footer-pad'>
<Navbar inverse={true} fixedBottom={true}>
<Navbar.Text>
Crane Operator browsing {this.state.registry.host}
Crane Operator browsing {this.props.registry.public_url}
</Navbar.Text>
<Navbar.Text pullRight>
<Navbar.Link href="https://github.com/parabuzzle/craneoperator" target="_blank">GitHub Project</Navbar.Link>
@ -45,3 +19,7 @@ export default class Footer extends React.Component {
);
}
}
Footer.propTypes = {
registry: React.PropTypes.object.isRequired
}

View File

@ -41,6 +41,10 @@ class CraneOp < Sinatra::Base
ENV['REGISTRY_SSL_VERIFY'] || 'true'
end
def registry_public_url
ENV['REGISTRY_PUBLIC_URL'] || "#{registry_host}:#{registry_port}"
end
## Authentication ##
if ENV['USERNAME']
@ -133,6 +137,7 @@ class CraneOp < Sinatra::Base
content_type :json
{
host: registry_host,
public_url: registry_public_url,
port: registry_port,
protocol: registry_proto,
ssl_verify: registry_ssl_verify