@@ -0,0 +1,249 @@
{ config , lib , pkgs , . . . }:
with lib ; with import ./common.nix { inherit lib ; } ;
let
cfg = config . virtualisation . openstack . glance ;
commonConf = ''
[ d a t a b a s e ]
c o n n e c t i o n = " m y s q l : / / ${ cfg . database . user } : ${ cfg . database . password . pattern } @ ${ cfg . database . host } / ${ cfg . database . name } "
n o t i f i c a t i o n _ d r i v e r = n o o p
[ k e y s t o n e _ a u t h t o k e n ]
a u t h _ u r l = ${ cfg . authUrl }
a u t h _ p l u g i n = p a s s w o r d
p r o j e c t _ n a m e = s e r v i c e
p r o j e c t _ d o m a i n _ i d = d e f a u l t
u s e r _ d o m a i n _ i d = d e f a u l t
u s e r n a m e = ${ cfg . serviceUsername }
p a s s w o r d = ${ cfg . servicePassword . pattern }
[ g l a n c e _ s t o r e ]
d e f a u l t _ s t o r e = f i l e
f i l e s y s t e m _ s t o r e _ d a t a d i r = / v a r / l i b / g l a n c e / i m a g e s /
'' ;
glanceApiConfTpl = pkgs . writeText " g l a n c e - a p i . c o n f " ''
${ commonConf }
[ p a s t e _ d e p l o y ]
f l a v o r = k e y s t o n e
c o n f i g _ f i l e = ${ cfg . package } / e t c / g l a n c e - a p i - p a s t e . i n i
'' ;
glanceRegistryConfTpl = pkgs . writeText " g l a n c e - r e g i s t r y . c o n f " ''
${ commonConf }
[ p a s t e _ d e p l o y ]
c o n f i g _ f i l e = ${ cfg . package } / e t c / g l a n c e - r e g i s t r y - p a s t e . i n i
'' ;
glanceApiConf = " / v a r / l i b / g l a n c e / g l a n c e - a p i . c o n f " ;
glanceRegistryConf = " / v a r / l i b / g l a n c e / g l a n c e - r e g i s t r y . c o n f " ;
in {
options . virtualisation . openstack . glance = {
package = mkOption {
type = types . package ;
example = literalExample " p k g s . g l a n c e " ;
description = ''
G l a n c e p a c k a g e t o u s e .
'' ;
} ;
enable = mkOption {
default = false ;
type = types . bool ;
description = ''
T h i s o p t i o n e n a b l e s G l a n c e a s a s i n g l e - m a c h i n e
i n s t a l l a t i o n . T h a t i s , a l l o f G l a n c e ' s c o m p o n e n t s a r e
e n a b l e d o n t h i s m a c h i n e . T h i s i s u s e f u l f o r e v a l u a t i n g a n d
e x p e r i m e n t i n g w i t h G l a n c e . N o t e w e a r e c u r r e n t l y n o t
p r o v i d i n g a n y c o n f i g u r a t i o n s f o r a m u l t i - n o d e s e t u p .
'' ;
} ;
authUrl = mkOption {
type = types . str ;
default = http://localhost:5000 ;
description = ''
C o m p l e t e p u b l i c I d e n t i t y ( K e y s t o n e ) A P I e n d p o i n t . N o t e t h i s i s
u n v e r s i o n n e d .
'' ;
} ;
serviceUsername = mkOption {
type = types . str ;
default = " g l a n c e " ;
description = ''
T h e G l a n c e s e r v i c e u s e r n a m e . T h i s u s e r i s c r e a t e d i f b o o t s t r a p
i s e n a b l e , o t h e r w i s e i t h a s t o b e m a n u a l l y c r e a t e d b e f o r e
s t a r t i n g t h i s s e r v i c e .
'' ;
} ;
servicePassword = mkSecretOption {
name = " g l a n c e A d m i n P a s s w o r d " ;
description = ''
T h e G l a n c e s e r v i c e u s e r ' s p a s s w o r d .
'' ;
} ;
database = databaseOption " g l a n c e " ;
bootstrap = {
enable = mkOption {
default = false ;
type = types . bool ;
description = ''
B o o t s t r a p t h e G l a n c e s e r v i c e b y c r e a t i n g t h e s e r v i c e t e n a n t ,
a n a d m i n a c c o u n t a n d a p u b l i c e n d p o i n t . T h i s o p t i o n p r o v i d e s
a r e a d y - t o - u s e g l a n c e s e r v i c e . T h i s i s o n l y d o n e a t t h e
f i r s t G l a n c e e x e c u t i o n b y t h e s y s t e m d p o s t s t a r t s e c t i o n .
T h e k e y s t o n e a d m i n a c c o u n t i s u s e d t o c r e a t e r e q u i r e d
K e y s t o n e r e s o u r c e f o r t h e G l a n c e s e r v i c e .
< n o t e > < p a r a > T h i s o p t i o n i s a h e l p e r f o r s e t t i n g u p
d e v e l o p m e n t o r t e s t i n g e n v i r o n m e n t s . < / p a r a > < / n o t e >
'' ;
} ;
endpointPublic = mkOption {
type = types . str ;
default = " h t t p : / / l o c a l h o s t : 9 2 9 2 " ;
description = ''
T h e p u b l i c i m a g e e n d p o i n t . T h e l i n k < l i n k
x l i n k : h r e f = " h t t p : / / d o c s . o p e n s t a c k . o r g / l i b e r t y / i n s t a l l - g u i d e - r d o / k e y s t o n e - s e r v i c e s . h t m l " >
c r e a t e e n d p o i n t < / l i n k > p r o v i d e s m o r e i n f o r m a t i o n s
a b o u t t h a t .
'' ;
} ;
keystoneAdminUsername = mkOption {
type = types . str ;
default = " a d m i n " ;
description = ''
T h e k e y s t o n e a d m i n u s e r n a m e u s e d t o c r e a t e t h e G l a n c e a c c o u n t .
'' ;
} ;
keystoneAdminPassword = mkSecretOption {
name = " k e y s t o n e A d m i n P a s s w o r d " ;
description = ''
T h e k e y s t o n e a d m i n u s e r ' s p a s s w o r d .
'' ;
} ;
keystoneAdminTenant = mkOption {
type = types . str ;
default = " a d m i n " ;
description = ''
T h e k e y s t o n e a d m i n t e n a n t u s e d t o c r e a t e t h e G l a n c e a c c o u n t .
'' ;
} ;
keystoneAuthUrl = mkOption {
type = types . str ;
default = " h t t p : / / l o c a l h o s t : 5 0 0 0 / v 2 . 0 " ;
description = ''
T h e k e y s t o n e a u t h u r l u s e d t o c r e a t e t h e G l a n c e a c c o u n t .
'' ;
} ;
} ;
} ;
config = mkIf cfg . enable {
# Note: when changing the default, make it conditional on
# ‘ system.stateVersion’ to maintain compatibility with existing
# systems!
virtualisation . openstack . glance . package = mkDefault pkgs . glance ;
users . extraUsers = [ {
name = " g l a n c e " ;
group = " g l a n c e " ;
uid = config . ids . gids . glance ;
} ] ;
users . extraGroups = [ {
name = " g l a n c e " ;
gid = config . ids . gids . glance ;
} ] ;
systemd . services . glance-registry = {
description = " O p e n S t a c k G l a n c e R e g i s t r y D a e m o n " ;
after = [ " n e t w o r k . t a r g e t " ] ;
path = [ pkgs . curl pkgs . pythonPackages . keystoneclient pkgs . gawk ] ;
wantedBy = [ " m u l t i - u s e r . t a r g e t " ] ;
preStart = ''
m k d i r - m 7 7 5 - p / v a r / l i b / g l a n c e / { i m a g e s , s c r u b b e r , i m a g e _ c a c h e }
c h o w n g l a n c e : g l a n c e / v a r / l i b / g l a n c e / { i m a g e s , s c r u b b e r , i m a g e _ c a c h e }
# S e c r e t f i l e m a n a g m e n t
c p ${ glanceRegistryConfTpl } ${ glanceRegistryConf } ;
c h o w n g l a n c e : g l a n c e ${ glanceRegistryConf } ;
c h m o d 6 4 0 ${ glanceRegistryConf }
${ replaceSecret cfg . database . password glanceRegistryConf }
${ replaceSecret cfg . servicePassword glanceRegistryConf }
c p ${ glanceApiConfTpl } ${ glanceApiConf } ;
c h o w n g l a n c e : g l a n c e ${ glanceApiConf } ;
c h m o d 6 4 0 ${ glanceApiConf }
${ replaceSecret cfg . database . password glanceApiConf }
${ replaceSecret cfg . servicePassword glanceApiConf }
# I n i t i a l i s e t h e d a t a b a s e
${ cfg . package } / b i n / g l a n c e - m a n a g e - - c o n f i g - f i l e = ${ glanceApiConf } - - c o n f i g - f i l e = ${ glanceRegistryConf } d b _ s y n c
'' ;
postStart = ''
s e t - e u
e x p o r t O S _ A U T H _ U R L = ${ cfg . bootstrap . keystoneAuthUrl }
e x p o r t O S _ U S E R N A M E = ${ cfg . bootstrap . keystoneAdminUsername }
e x p o r t O S _ P A S S W O R D = ${ getSecret cfg . bootstrap . keystoneAdminPassword }
e x p o r t O S _ T E N A N T _ N A M E = ${ cfg . bootstrap . keystoneAdminTenant }
# W a i t u n t i l t h e k e y s t o n e i s a v a i l a b l e f o r u s e
c o u n t = 0
w h i l e ! k e y s t o n e u s e r - g e t ${ cfg . bootstrap . keystoneAdminUsername } > / d e v / n u l l
d o
i f [ $c o u n t - e q 3 0 ]
t h e n
e c h o " T r i e d 3 0 t i m e s , g i v i n g u p . . . "
e x i t 1
f i
e c h o " K e y s t o n e n o t y e t s t a r t e d . W a i t i n g f o r 1 s e c o n d . . . "
c o u n t = $( ( c o u n t + + ) )
s l e e p 1
d o n e
# I f t h e s e r v i c e g l a n c e d o e s n ' t e x i s t , w e c o n s i d e r g l a n c e i s
# n o t i n i t i a l i z e d
i f ! k e y s t o n e s e r v i c e - g e t g l a n c e
t h e n
k e y s t o n e s e r v i c e - c r e a t e - - t y p e i m a g e - - n a m e g l a n c e
I D = $( k e y s t o n e s e r v i c e - g e t g l a n c e | a w k ' / i d / { p r i n t $4 } ' )
k e y s t o n e e n d p o i n t - c r e a t e - - r e g i o n R e g i o n O n e - - s e r v i c e $I D - - i n t e r n a l u r l h t t p : / / l o c a l h o s t : 9 2 9 2 - - a d m i n u r l h t t p : / / l o c a l h o s t : 9 2 9 2 - - p u b l i c u r l ${ cfg . bootstrap . endpointPublic }
k e y s t o n e u s e r - c r e a t e - - n a m e ${ cfg . serviceUsername } - - t e n a n t s e r v i c e - - p a s s ${ getSecret cfg . servicePassword }
k e y s t o n e u s e r - r o l e - a d d - - t e n a n t s e r v i c e - - u s e r ${ cfg . serviceUsername } - - r o l e a d m i n
f i
'' ;
serviceConfig = {
PermissionsStartOnly = true ; # preStart must be run as root
TimeoutStartSec = " 6 0 0 " ; # 10min for initial db migrations
User = " g l a n c e " ;
Group = " g l a n c e " ;
ExecStart = " ${ cfg . package } / b i n / g l a n c e - r e g i s t r y - - c o n f i g - f i l e = ${ glanceRegistryConf } " ;
} ;
} ;
systemd . services . glance-api = {
description = " O p e n S t a c k G l a n c e A P I D a e m o n " ;
after = [ " g l a n c e - r e g i s t r y . s e r v i c e " " n e t w o r k . t a r g e t " ] ;
requires = [ " g l a n c e - r e g i s t r y . s e r v i c e " " n e t w o r k . t a r g e t " ] ;
wantedBy = [ " m u l t i - u s e r . t a r g e t " ] ;
serviceConfig = {
PermissionsStartOnly = true ; # preStart must be run as root
User = " g l a n c e " ;
Group = " g l a n c e " ;
ExecStart = " ${ cfg . package } / b i n / g l a n c e - a p i - - c o n f i g - f i l e = ${ glanceApiConf } " ;
} ;
} ;
} ;
}